android studio使用Aidl跨进程调用服务
来源:互联网 发布:王奕霏编程 编辑:程序博客网 时间:2024/06/03 20:13
以前就知道其大概代码流程,但是一直没有敲代码去实现,今天将其实现了,android studio下编写也遇到了一些小细节的问题,特此记录一下。
既然是模拟Aidl通讯,那么当然要编写两个应用了,一个提供服务给另一个应用调用,那么开始吧。
一、服务提供方应用编写
①.为了更全面一些,我编写了一个自定义类Book在Aidl之中传递,不同进程间传递自定义对象必须实现Parcelable接口,Serializable是不行的哦。Book类如下:
package com.lbb.aidltest.bean;import android.os.Parcel;import android.os.Parcelable;/** * 作者:李少波 * 邮箱:lishaobo@seengene.com * 日期:16/10/20 */public class Book implements Parcelable{ private String name; private int id; public Book(String name, int id) { this.name = name; this.id = id; } protected Book(Parcel in) { name = in.readString(); id = in.readInt(); } public static final Creator<Book> CREATOR = new Creator<Book>() { @Override public Book createFromParcel(Parcel in) { return new Book(in); } @Override public Book[] newArray(int size) { return new Book[size]; } }; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel parcel, int i) { parcel.writeString(name); parcel.writeInt(id); }}
②.编写.Aidl文件,因为此处用到了自定义类的对象的传递,所以需要编写两类aidl文件,分别是定义服务接口的和定义自定义类的aidl文件。
a.定义服务接口。右键-new-aidl-aidl file,文件名随便定义,可以是服务的类名前边加I。就像一个接口文件一样声明对外开放的方法即可,此处需要注意的是:如果用到了自定义类,则需要显示的import进来,此处需要显示import com.lbb.aidltest.bean.Book,否则会”Execution failed for task :app:compileDebugAidl”。我的接口定义文件如下:
// IAidlInterface.aidlpackage com.lbb.aidltest;import com.lbb.aidltest.bean.Book;interface IAidlInterface { Book getBookByIndex(int index);}
b.定义需要在进程间传递的自定义类同名的.aidl文件,此处是Book.aidl。这一步不能右键创建aidl file了,因为输入Book会提示”Interface Name must be unique”,导致无法下一步。所以只能在aidl文件夹下创建和Book一样的包路径,并在路径下new-file,填入Book.aidl,手动输入文件内容如下(全程系统无任何提示输入。。汗):
package com.lbb.aidltest.bean;parcelable Book;
③.万事俱备,创建自己的AidlService继承自Service,在onBind中返回一个.Stub自类的对象供其它app中使用,我的服务代码如下:
package com.lbb.aidltest;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.os.RemoteException;import android.support.annotation.Nullable;import com.lbb.aidltest.bean.Book;/** * 作者:李少波 * 邮箱:lishaobo@seengene.com * 日期:16/10/20 */public class AidlService extends Service { IAidlInterface.Stub mStub = new IAidlInterface.Stub() { @Override public Book getBookByIndex(int index) throws RemoteException { Book book = null; if(index ==0){ book = new Book("第一本书",0); } return book; } }; @Nullable @Override public IBinder onBind(Intent intent) { return mStub; }}
至此服务供应方代码编写完毕,对了,还有一点很重要,记得在mainfest中声明服务的隐式intent-filter,因为其它app都是用隐式方式调用这个服务的:
<service android:name=".AidlService"><intent-filter><action android:name="com.lbb.aidltest.AidlService"></action></intent-filter> </service>
二、调用其它app中可以被调用的服务。此处我调用我上一个app中的服务,前提是安装了上一个app哦。。使用过程分两步:
①.带上包名拷贝上一个app中的bean和aidl文件(包括自定义类以及接口的都要),也就是使用端要和提供端的bean的包路径以及aidl的包路径是一样的,没有路径创造路径也要保证一样。
②.在Activity中愉快的引用其他app服务吧,这里是隐式调用的,如果直接隐式调用在android 5.0之后的环境下会报”只能显式启动Service”的错误,此处用了一个网上荡的方法,可以用隐式打开服务了,我是这样使用的:
public class MainActivity extends Activity { private IAidlInterface aidlService; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final Intent intent = new Intent(); intent.setAction("com.lbb.aidltest.AidlService"); final Intent eintent = new Intent(createExplicitFromImplicitIntent(this,intent)); bindService(eintent,serviceConnection, Service.BIND_AUTO_CREATE); } private ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { aidlService = IAidlInterface.Stub.asInterface(iBinder); try { Book book = aidlService.getBookByIndex(0); Log.d(MainActivity.class.getSimpleName(),"book名字: "+book.getName()); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName componentName) { } }; @Override protected void onDestroy() { super.onDestroy(); unbindService(serviceConnection); } public static Intent createExplicitFromImplicitIntent(Context context, Intent implicitIntent) { // Retrieve all services that can match the given intent PackageManager pm = context.getPackageManager(); List<ResolveInfo> resolveInfo = pm.queryIntentServices(implicitIntent, 0); // Make sure only one match was found if (resolveInfo == null || resolveInfo.size() != 1) { return null; } // Get component info and create ComponentName ResolveInfo serviceInfo = resolveInfo.get(0); String packageName = serviceInfo.serviceInfo.packageName; String className = serviceInfo.serviceInfo.name; ComponentName component = new ComponentName(packageName, className); // Create a new intent. Use the old one for extras and such reuse Intent explicitIntent = new Intent(implicitIntent); // Set the component to be explicit explicitIntent.setComponent(component); return explicitIntent; }}
三、小结
1.提供端接口aidl文件创建需要手动import 自定义类,自定义类的aidl需要全手工填写包名并parcelable Book;
2.使用端要拷贝提供端的bean和aidl文件,并且在android 5.0以上系统需要用以上的方式来使得隐式bindService变为显式bind。
3.aidl调用第一个应用服务,不需要启动第一个应用哦
demo下载链接:
http://download.csdn.net/detail/lishaobo211985/9659733
- android studio使用Aidl跨进程调用服务
- android studio使用Aidl跨进程调用服务
- android跨进程调用Service(AIDL服务)
- Android IPC机制(三)在Android Studio中使用AIDL实现跨进程方法调用
- Android IPC机制(三)在Android Studio中使用AIDL实现跨进程方法调用
- Android IPC机制(三)在Android Studio中使用AIDL实现跨进程方法调用
- 跨进程调用Service(AIDL服务)
- 跨进程调用Service(AIDL服务)
- 跨进程调用Service(AIDL 服务)
- Android---44---使用AIDL Service 实现跨进程调用Service
- android中使用aidl和callback实现跨进程调用
- AIDL 使用详解 (一) Android跨进程调用
- android studio AIDL跨进程通信
- Android Studio AIDL实现跨进程通信
- Android Studio实现AIDL跨进程通信
- Android AIDL 跨进程服务 Proxy/Stub
- Android跨进程访问(AIDL服务)
- android中的跨进程服务组件aidl
- Android启动模式
- DB2 mainframe support UNICODE
- 【codeforces 732D】【二分+贪心】
- 判断2..100以内的质数--sqrt
- 死锁剖析
- android studio使用Aidl跨进程调用服务
- 微信网页小游戏开发实践——走过的坑
- Java面向对象7——toString和equals
- Android应用将"清除数据"项变为"管理空间",自定义数据清除
- Uva11997 K Smallest Sums
- DSNTIAUL UNLOAD DB2 TABLE INTO DATASET
- Android 差量更新实践
- redhat7.2 安装VCL
- JAVA 封装