该文章不解释Binder的定义和作用,只讲解,如何理解和实现一个Binder通信。因为Binder有定义规则,如果不是工作上经常需要定义Binder的同学,可能会在做过一段时间之后,又忘记了这个流程。我就是这样,因此需要从理解的角度,来固化我们的记忆。
一、定义Binder的切入口
我们要定义Binder,肯定是为了实现某个功能,比如,多个应用的跨进程通信,从事系统应用或FW开发的同学,经常需要做这种工作。这里我们就以实现A和B两个应用的通信为例。
二、定义流程
1、两个进程要通信什么?
我们这里以一问一答为例:A【客户端】发两个整数,B【服务端】回两个整数的和。
那么,我们就得定义一个aidl接口,这个接口文件的命名规则是需要在与java同层级定义个aidl目录,*.aidl结尾。
例:app/src/main/aidl/com/example/aidldemo/ICount.aidl
package com.example.aidldemo;
interface ICount {
int sum(int a, int b);
}
2、定义完接口后,我们要实现这个接口的功能
public class TestService extends Service {
private final ICount.Stub mBinder = new ICount.Stub() {
@Override
public int add(int a, int b) {
return a + b;
}
};
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
}
<service
android:name=".TestService "
android:exported="true"
android:process=":remote">
<intent-filter>
<action android:name="com.example.aidldemo.ICount" />
</intent-filter>
</service>
3、服务端的实现好了,现在客户端需要去绑定它。
// 绑定服务
Intent intent = new Intent("com.example.aidldemo.ICount");
intent.setPackage("com.example.aidldemo"); // 服务端包名
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
private ICount mService;
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mService = ICount.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
mService = null;
}
};
有了这个mService对象后,我们就可以跨进程去调用服务端的接口,实现计算两个整数的和的功能。
try {
int result = mService.add(3, 5);
Log.d("AIDL", "Result: " + result); // 输出 8
} catch (RemoteException e) {
e.printStackTrace();
}