以前面试被问到AIDL我就觉得害怕,因为项目中没用到啊。但面试回来后往往又忘记再学习下,下次面试依旧不会。最近学习了下,感觉并没有那么难。
什么是AIDL
AIDL全称“Android Interface Definition Language”,Android接口定义语言。是Android系统上用于进程和进程间通信。
AIDL的实现
实现这样一个案例,DemoB获取DemoA中SharePreferences中的值。
1 服务端实现
服务端不是指服务器,而是我们的DemoA。因为我们最终要实现的是在DemoB上操作获取DemoA上的数据,整个过程没有DemoA的操作。我们直接操作的一端(DemoB)在这个过程中称之为客户端,相应的没有直接操作,提供服务支持的一端(DemoA)称为服务端。
- 1 创建一个Android项目,为DemoA
- 2 在项目中创建一个aidl的文件夹
AndroidStudio已经给我提供了该文件夹的快捷创建方式:
- 3 在aidl文件夹中创建一个aidl文件
AndroidStudio同样也提供了直接创建该类型文件的方式,上图第一行即是,里面内容如下:
package com.fullcat.demo.a;
interface ISPInterface {
String getValue(String key);
}
注意第一行包名要与aidl文件所在包名一致。
- 4 绑定service
创建一个service,代码如下:
public class RemoteSPService extends Service {
private IBinder iBinder = new ISPInterface.Stub() {
@Override
public String getValue(String key) {
SharedPreferences sp = getSharedPreferences("demo_a", MODE_PRIVATE);
String value = sp.getString(key, null);
return value;
}
};
@Override
public IBinder onBind(Intent intent) {
return iBinder;
}
}
- 5 在Manifest文件中注册
<service android:name=".RemoteSPService"
android:exported="true"/>
需要添加android:exported=“true”,客户端无法绑定。
2 客户端实现
- 1 创建一个Android项目,为DemoB
- 2 将DemoA中的ISPInterface.aidl 复制到DemoB的aidl文件夹中。DemoB的aidl文件夹中也要有相同的包名
- 3 绑定远程service,获取IBinder对象
private ISPInterface mIBinder;
...
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.fullcat.demo.a",
"com.fullcat.demo.a.RemoteSPService"));
bindService(intent, new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
mIBinder = ISPInterface.Stub.asInterface(iBinder);
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
mIBinder=null
}
}, BIND_AUTO_CREATE);
- 4 调用aidl中定义的方法
if (mIBinder != null) {
String value = mIBinder.getValue("aidl");
}