1. 定义client端,service端,service对外暴露接口
2.服务端的开启方式为bindService( ),不是startService()
3.android 5.0之后隐式调用被屏蔽,需要使用新的方式
4.Binder通信原理,系统自动生成aidl代码作用分析
5.android studio中生成aidl注意事项
6.client端清单文件和service端清单文件设置注意
2. service通过后缀.aidl向外暴露接口,android studio 可以直接创建Aidl文件,生成的文件
(图1 AIDL创建)
(图2 AIDL文件)
1.1 如果没有生成相应的文件则需要在工程buildConfigue 中添加入下配置即可顺利生成对应的文件
sourceSets {
main {
manifest.srcFile 'src/main/AndroidManifest.xml'
java.srcDirs = ['src/main/java', 'src/main/aidl']
resources.srcDirs = ['src/main/java', 'src/main/aidl']
aidl.srcDirs = ['src/main/aidl']
res.srcDirs = ['src/main/res']
assets.srcDirs = ['src/main/assets']
}
}
客户端和服务端配置都需要添加,否则导致编译不通过
1.2. 如果需要测试传递对象参数的,则需要使用Parcelable进行序列化,为什么不用Serializable,请看这篇blog url
2.服务端的开启方式为bindService( ),不是startService()?
简单总结就是使用startService()方法启用服务,调用者与服务之间没有关连,即使调用者退出了,服务仍然运行。使用bindService()方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止,大有“不求同时生,必须同时死”的特点。
3.android 5.0之后隐式调用被屏蔽,需要使用新的方式
private void bindService() {
Intent intent = new Intent();
intent.setAction("com.nuoyuan.server.RemoteServiceIpc"); //清单文件声明的intent-filter
Intent eintent = new Intent(createExplicitFromImplicitIntent(this, intent));
bindService(eintent, romoteServer, Service.BIND_AUTO_CREATE);
}
//###系统提供的解决方案
public static Intent createExplicitFromImplicitIntent(Context context, Intent implicitIntent) {
// Retrieve all services that can match the given intent
PackageManager pm = context.getPackageManager();
List<ResolveInfo> resolveInfo = pm.queryIntentServices(implicitIntent, 0);
// Make sure only one match was found
if (resolveInfo == null || resolveInfo.size() != 1) {
return null;
}
// Get component info and create ComponentName
ResolveInfo serviceInfo = resolveInfo.get(0);
String packageName = serviceInfo.serviceInfo.packageName;
String className = serviceInfo.serviceInfo.name;
ComponentName component = new ComponentName(packageName, className);
// Create a new intent. Use the old one for extras and such reuse
Intent explicitIntent = new Intent(implicitIntent);
// Set the component to be explicit
explicitIntent.setComponent(component);
return explicitIntent;
}
4.Binder通信原理,系统自动生成aidl代码作用分析
IBinder/IInterface/Binder/BinderProxy/Stub
我们使用AIDL接口的时候,经常会接触到这些类,那么这每个类代表的是什么呢?
oIBinder是一个接口,它代表了一种跨进程传输的能力;只要实现了这个接口,就能将这个对象进行跨进程传递;这是驱动底层支持的;在跨进程数据流经驱动的时候,驱动会识别IBinder类型的数据,从而自动完成不同进程Binder本地对象以及Binder代理对象的转换。
oIBinder负责数据传输,那么client与server端的调用契约(这里不用接口避免混淆)呢?这里的IInterface代表的就是远程server对象具有什么能力。具体来说,就是aidl里面的接口。
oJava层的Binder类,代表的其实就是Binder本地对象。BinderProxy类是Binder类的一个内部类,它代表远程进程的Binder对象的本地代理;这两个类都继承自IBinder, 因而都具有跨进程传输的能力;实际上,在跨越进程的时候,Binder驱动会自动完成这两个对象的转换。
o在使用AIDL的时候,编译工具会给我们生成一个Stub的静态内部类;这个类继承了Binder, 说明它是一个Binder本地对象,它实现了IInterface接口,表明它具有远程Server承诺给Client的能力;Stub是一个抽象类,具体的IInterface的相关实现需要我们手动完成,这里使用了策略模式
Blog url:http://weishu.me/2016/01/12/binder-index-for-newer/ binder通信原理
5.android studio中生成aidl注意事项
之前在enclipse 写没有问题,到android studio一直编译不通过。从eclipse 到studio集成主要注意几个方面。
5.1 bulidConfig 设置
sourceSets {
main {
manifest.srcFile 'src/main/AndroidManifest.xml'
java.srcDirs = ['src/main/java', 'src/main/aidl']
resources.srcDirs = ['src/main/java', 'src/main/aidl']
aidl.srcDirs = ['src/main/aidl']
res.srcDirs = ['src/main/res']
assets.srcDirs = ['src/main/assets']
}
}
指定具体编译生成路径
5.2 client端需要将服务端的aidl文件夹直接拷贝过去使用.负责找不到具体的路径。如果需要使用aidl传递对象的。需对该对象进行序列化。并且新建.aidl文件
6.client端清单文件和service端清单文件设置注意
(图服务端)
(图客户端)
Demo 地址:http://pan.baidu.com/s/1cn7sXw
http://weishu.me/2016/01/12/binder-index-for-newer/ binder通信原理