AIDL(Android Interface Definition Language),实际使用其实也是绑定一个Service。
1. 一个.aidl接口定义示例
2. 建立连接:
final Intent serviceIntent = ApiAvailability.getInstance().getAvailableServicesInstance(context);
isServiceConnecting.set(context.bindService(serviceIntent, o3drServicesConnection, Context.BIND_AUTO_CREATE));
关键是bindService的前两个参数
3. 第二个参数ServiceConnection
private final ServiceConnection o3drServicesConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// 绑定服务成功
}
@Override
public void onServiceDisconnected(ComponentName name) {
// 绑定服务失败
}
};
4. 绑定服务成功内的操作,需要的几个关键方法
Stub.asInterface(IBinder)
// 获取AIDL接口对象
asBinder()
// 获取binder对象
asBinder().linkToDeath()
// 注册断开监听
asBinder().unlinkToDeath()
// 取消断开监听
asBinder().pingBinder()
// 判断是否还连接
4.1 获取 IDroidPlannerServices这个AIDL接口对象
// 最后的参数就是 onServiceConnected() 回调中的IBinder对象
IDroidPlannerServices o3drServices = IDroidPlannerServices.Stub.asInterface(service);
4.2 利用接口对象注册Binder断掉的监听
// binderDeathRecipient 是监听对象
o3drServices.asBinder().linkToDeath(binderDeathRecipient, 0);
4.3 判断是否还连接
o3drServices.asBinder().pingBinder();
4.4 取消Binder断掉的监听,一般在unbindService时
o3drServices.asBinder().unlinkToDeath(binderDeathRecipient, 0);
context.unbindService(o3drServicesConnection);
4.5 AIDL接口对象中定义的方法使用
例如上面图片中的 getServiceVersionCode() 等方法。
5. 第一个参数Intent
Intent getAvailableServicesInstance(@NonNull final Context context) {
final PackageManager pm = context.getPackageManager();
//Check if an instance of the services library is up and running.
final Intent serviceIntent = new Intent(SERVICES_CLAZZ_NAME);
final List<ResolveInfo> serviceInfos = pm.queryIntentServices(serviceIntent, PackageManager.GET_META_DATA);
if(serviceInfos != null && !serviceInfos.isEmpty()){
for(ResolveInfo serviceInfo : serviceInfos) {
final Bundle metaData = serviceInfo.serviceInfo.metaData;
if (metaData == null)
continue;
final int coreLibVersion = metaData.getInt(METADATA_KEY, INVALID_LIB_VERSION);
// 服务已经被其它进程启动并且版本高于设定版本,使用此服务
if (coreLibVersion != INVALID_LIB_VERSION && coreLibVersion >= VersionUtils.getCoreLibVersion(context)) {
serviceIntent.setClassName(serviceInfo.serviceInfo.packageName, serviceInfo.serviceInfo.name);
return serviceIntent;
}
}
}
//Didn't find any that's up and running. Enable the local one
DroidPlannerService.enableDroidPlannerService(context, true);
serviceIntent.setClass(context, DroidPlannerService.class);
return serviceIntent;
}
首次启动这个服务时,enableDroidPlannerService() 很关键,具体如下:
public static void enableDroidPlannerService(Context context, boolean enable){
final ComponentName serviceComp = new ComponentName(context, DroidPlannerService.class);
final int newState = enable ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
: PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
context.getPackageManager().setComponentEnabledSetting(serviceComp, newState, PackageManager.DONT_KILL_APP);
}
最后还有在Manifest.xml中对 DroidPlannerService 的注册:
<service
android:name="org.droidplanner.services.android.impl.api.DroidPlannerService"
android:enabled="false">
<!-- Filter and meta data for the Tower lib runtime -->
<!-- 有intent-filter所以android:exported属性默认为true -->
<intent-filter>
<action android:name="com.o3dr.services.android.lib.model.IDroidPlannerServices" />
</intent-filter>
<meta-data
android:name="com.o3dr.dronekit.android.core.version"
<!-- 版本号的配置 -->
android:value="30200" />
</service>