1. AIDL是什么
AIDL即接口定义语言,可以利用它定义客户端与服务均认可的编程接口,以便二者使用进程间通信 (IPC) 进行相互通信。
在 Android 中,一个进程通常无法访问另一个进程的内存。因此,为进行通信,进程需将其对象分解成可供操作系统理解的原语,并将其编组为可供您操作的对象。编写执行该编组操作的代码较为繁琐,因此 Android 会使用 AIDL 为您处理此问题。
在我看来,接口定义语言,相当于一个脚本,可以根据某些规则来生成一些代码,从而实现某种功能。
注意:只有在需要不同应用的客户端通过 IPC 方式访问服务,并且希望在服务中进行多线程处理时,您才有必要使用 AIDL。如果您无需跨不同应用执行并发 IPC,则应通过实现 Binder 来创建接口;或者,如果您想执行 IPC,但不需要处理多线程,请使用 Messenger 来实现接口。
2. 支持的基本数据类型
// IMyAidlInterface.aidl
package com.example.testaidl;
// Declare any non-default types here with import statements
interface IMyAidlInterface {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
double aDouble, String aString);
}
可以支持的数据类型有
- 基本数据类型: int、long、char、boolean、float、double。
- String、CharSequence
- List: 只支持ArrayList,里面每个元素都必须能够被AIDL支持。
- Map: 只支持HashMap,里面每个元素都必须被AIDL支持,包括key和value。
- Parcelable: 所有实现了Parcelable接口的对象。
- AIDL: 所有的AIDL接口本身也可以在AIDL文件中使用。
3. 服务端
提供接口,供其他应用调用的称为服务端。
- 创建包名com.example.testaidl的Module
- 创建IAidlServer.aidl
// IAidlServer.aidl
package com.example.aidl_server;
// Declare any non-default types here with import statements
interface IAidlServer {
int add(int first,int second);
}
创建AIDL文件,然后Make Project,生成IAidlServer接口文件
- 创建Service
public class IRemoteService extends Service {
private static final String TAG = "IRemoteService";
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
private IBinder mBinder = new IAidlServer.Stub() {
@Override
public int add(int first, int second) throws RemoteException {
Log.d(TAG, "收到远程请求,输入的参数为" + first + "和" + second);
return first + second;
}
};
}
IRemoteService供客户端进行绑定,绑定以后会回调一个Binder对象,这个Binder对象和上一篇文章讲到的Binder在实质上一样,都是Binder对象,只是对象的实例方式不一样。
- 注册Service
<service
android:name=".IRemoteService"
android:exported="true">
<intent-filter>
<action android:name="com.example.aidl"></action>
</intent-filter>
</service>
注册Service的同时,约定bindService的action。
4. 客户端
调用其他应用接口的被称为客户端。
- 创建包名为com.example.testaidl的Moudle
- 把服务端中aidl完整的文件夹拷贝到位于main下面的相同位置
- 绑定Service
Intent intent = new Intent();
intent.setPackage("com.example.aidl_server");
intent.setAction("com.example.aidl");
bindService(intent, mServiceConnection, BIND_AUTO_CREATE);
指定包名和action
- 回调获取服务端Binder对象
private ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
mAidlServer = IAidlServer.Stub.asInterface(iBinder);
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
mAidlServer = null;
}
};
onServiceConnected是建立连接时的回调,onServiceDisconnected是断开连接时的回调。
- 调用服务端方法
try {
int first_num = Integer.parseInt(ed_firtst.getText().toString());
int second_num = Integer.parseInt(ed_second.getText().toString());
int value = mAidlServer.add(first_num, second_num);
Log.d(TAG, "经过远程计算,两个Int值相加的结果为" + value);
} catch (RemoteException e) {
e.printStackTrace();
}
2019-09-19 22:21:49.140 5387-5387/com.example.testaidl D/MainActivity: 经过远程计算,两个Int值相加的结果为9
5. 项目地址
https://pan.baidu.com/s/1Mx5MW8DuzWHOYC5_V5kYAQ
6. 后续
如果大家喜欢这篇文章,欢迎点赞!
如果想看更多 IPC 方面的文章,欢迎关注!
网友评论