Android进程间通讯——AIDL
16lz
2021-01-26
AIDL (Android Interface Definition Language) ,用于生成可以在Android设备上两个进程之间进行进程间通信(interprocess communication, IPC)的代码。在使用AIDL前,必须要绑定service——bindService。
使用AIDL的步骤:
1.创建一个包名用来存放aidl文件,如果需要传递自定义对象,还需要建立对象的aidl文件,这里我们由于使用了自定义对象Student,所以,还需要创建Student.aidl和Student.java(两者必须同名)。注意,这三个文件,需要都放在同一个包里。
说明:
aidl中支持的参数类型为:基本类型(int,long,char,boolean等),String,CharSequence,List,Map,其他类型必须使用import导入
接口中的参数除了aidl支持的类型,其他类型必须标识其方向:到底是输入还是输出抑或两者兼之,用in,out或者inout来表示,
2.Student.aidl代码如下:
package com.fy.market.aidl;parcelable Student;说明:这里parcelable是个类型,首字母是小写的,和Parcelable接口不是一个东西,接口和方法声明都不用public,方法加入public会提示错误。
通过AIDL传输非基本类型的对象,被传输的对象需要序列化
在gen下面可以看到,eclipse为我们自动生成了一个代理类 public static abstract class Stub extends android.os.Binder implements com.ryg.sayhi.aidl.IMyService 可见这个Stub类就是一个普通的Binder,只不过它实现了我们定义的aidl接口。它还有一个静态方法 public static com.ryg.sayhi.aidl.IMyService asInterface(android.os.IBinder obj) 这个方法很有用,通过它,我们就可以在客户端中得到IMyService的实例,进而通过实例来调用其方法 3.服务端(service) 实现
@Overridepublic IBinder onBind(Intent intent) {// TODO Auto-generated method stubdisplayNotificationMessage("服务已启动"); return mBinder; }
和
private final IMyService.Stub mBinder =new IMyService.Stub() {@Overridepublic List<Student> getStudent() throws RemoteException {// TODO Auto-generated method stubsynchronized (mStudents) {return mStudents;}}@Overridepublic void addStudent(Student student) throws RemoteException {// TODO Auto-generated method stubsynchronized (mStudents) {if (!mStudents.contains(student)) {mStudents.add(student);}}}/*** 在这里可以做权限认证,return false意味着客户端的调用就会失败,比如下面,只允许包名为com.example.test的客户端通过,* 其他apk将无法完成调用过程 */@Overridepublic boolean onTransact(int code, Parcel data, Parcel reply, int flags)throws RemoteException {// TODO Auto-generated method stubString packageName = null;String[] packages = AIDLService.this.getPackageManager().getPackagesForUid(getCallingUid());if (packages != null && packages.length > 0) {packageName = packages[0];}if (!PACKAGE_SAYHI.equals(packageName)) {return false;}return super.onTransact(code, data, reply, flags); }};4.客户端(clident) 实现接口ServiceConnection,并拿到服务端返回的I Binder
@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {// TODO Auto-generated method stub //通过服务端onBind方法返回的binder对象得到IMyService的实例,得到实例就可以调用它的方法了 mIMyService = IMyService.Stub.asInterface(service); try { if (mIMyService.getStudent().size()>0) { Student student = mIMyService.getStudent().get(mIMyService.getStudent().size()-1); showDialog(student.toString()); }} catch (RemoteException e) {// TODO Auto-generated catch blocke.printStackTrace();} }理解: 进程Activity通过bindService(intent, ServiceConnection, BIND_AUTO_CREATE);启动Service,也就是开启进程Service,并且将 ServiceConnection传递到Service中,关于ServiceConnection的作用: /**
* Interface for monitoring the state of an application service. See
* {@link android.app.Service} and
* {@link Context#bindService Context.bindService()} for more information.
* <p>Like many callbacks from the system, the methods on this class are called
* from the main thread of your process.
*/ 我的理解是类似于Callback,但仅仅是类似,并不是真正的callback,两个进程间没法实现callback,这也间接的说明了onBind返回的和onServiceConnected 中的Service不是一个IBind。启动到Service,然后Service中实现private final IMyService.Stub mBinder =new IMyService.Stub() ;并通过onBind返回给Activity,Activity实现接口ServiceConnection的onServiceConnected方法拿到实现了的自定义的aidl接口(拿到的和Service中的不是同一个)。 参考资料: http://blog.csdn.net/singwhatiwanna/article/details/17041691#reply demo:(
里面只有activity.java和service.java两个文件,因为很多的实验都写在了一个工程中,所以只能拿出这两个文件,你需要自建工程,并在清单文件中声明(service 必须有android:process=":remote",要不和activity在同一进程中)):点击打开链接
更多相关文章
- android之数据库和Content Provider(二)
- android 面试经典(4)
- android Camera api1和api2学习笔记
- Android中MimeType的用途
- Button控件
- Android(安卓)BLE蓝牙开发中读取数据时设置Notify的方法
- Android(安卓)的NumberPicker相关问题
- Android(安卓)MimeType的用途以及所有类型
- Android(安卓)解析如何获取SDCard 内存