进程名以":"开头的讲程属于当前应用的私有进程,其余应用的组件不能够和它跑在同一个进程中,而进程名不以开头的进程属于全局进程, 其余应用经过ShareUID方式能够和它跑在同一个进程中。缓存
咱们知道Andrid系统会为每一个应用分配一个惟一的UID,具备相同UID的应用才能共享数据。这里要说明的是,两个应用经过ShareUID跑在同一个进程中是有要求的,须要这两个应用有相同的ShareUID而且签名相同才能够。在这种状况下,它们能够互相访问对方的私有数据,好比data目录、组件信息等,无论它们是否跑在同一个进程中。 固然若是它们跑在同一个进程中,那么除了能共享data目录、组件信息,还能够共享内存数据,或者说它们看起来就像是一个应用 的两个部分。bash
Messenger能够翻译为信使,顾名思义,经过它能够在不一样进程中传递Mesge对象, 在Message中放入咱们须要传递的数据,就能够轻松地实现数据的进程间传递了网络
服务端进程socket
首先,咱们须要在服务端建立一个Service来处理客户端的链接请求,同时建立一个Handler并经过它来建立个Messenger对象,而后在Service的onBind中返回这个Messenger对象底层的Binder便可。ide
客户端进程ui
客户端进程中,首先要绑定服务端的Service, 绑定成功后用服务端返回的IBinder 对 象建立一个Messenger,经过这个Messenger 就能够向服务端发送消息了,发消息类型为 Message 对象。若是须要服务端可以回应客户端,就和服务端一*样,咱们还须要建立 一个 Handler并建立一个新的Messenger, 并把这个Messenger对象经过Message的replyTo参数 传递给服务端,服务端经过这个replyTo参数就能够回应客户端。spa
直观来讲,Binder 是Android中的一个类, 它实现了IBinder 接口。从IPC 角度来讲, Binder是Android中的一种跨进 程通讯方式,Binder 还能够理解为一种虚拟的物理设备,它的设备驱动是/dev/binder,该通讯方式在Linux中没有;从Android Framework角度来讲Binder是ServiceManager链接各类Manager (ActivityManager、WindowManager,等等)相应ManagerService的桥梁;线程
从Android 应用层来讲,Binder 是客户端和服务端进行通化的媒介,当bindService 的时候,服务端会返回一一个包含了服务端业务调用的Binder对象经过这个Binder对象,客户端就能够获取服务端提供的服务或者数据,这里的服务包括通服务和基于AIDL的服务。翻译
Android开发中,Binder主要用在Service中,包括AIDL和Messenger,其中普通Serv中的Binder不涉及进程间通讯,因此较为简单,没法触及Binder的核心,而Messenget底层实际上是AIDL。代理
aidl文件中使用了自定义的Parcelable对象和aidl对象必须显式import进来,同一个包路径下也要导入
aidl文件中使用了自定义的Parcelable对象,那必须建立一个和自定义的Parcelable对象同名的aidl文件,而且在使用到这个对象的aidl文件中声名它为Parcelable类型
parcelable User;
复制代码
aidl文件中每一个实现Parcelable接口的类都须要声名parcelable,以外除了基本数据类型,其余类型参数必须标上方向:in out inout
interface IBookManager{
void addBook(in Book book);
}
复制代码
aidl接口只支持方法,不支持声明静态常量
aidl的包结构在服务端和客户端要保持一直.由于客户端须要反序列化服务端中和aidl接口相关的全部类,类的完整路径不同反序列化失败
aidl方法是在服务端的Binder线程池中执行,CopyOnWriteArrayList自动线程同步,还有ConcurrentHashMap
RemoteCallbackList,自动线程同步,进程终止时自动移除注册的listener;beginBroadcast()和finishBroadcast()必须配对使用
服务端aidl接口方法所有运行在Binder线程池中,接口方法能够作耗时操做,若是调用接口的客户端是在UI线程中,那么不要再接口方法中作耗时操做不然就会致使ANR;若是明确知道必须作耗时操做,那么在调用接口的客户端中须要开启线程来调用耗时的aidl接口方法
客户端中的aidl接口运行在客户端的线程池中,不能作刷新UI;
服务端在UI线程中(好比在onBind方法中获取客户端的相关信息)调用客户端耗时的aidl接口,会致使服务端ANR
客户端的onServiceConnected()和onServiceDisconnected()运行在UI线程
private IBinder.DeathRecipient recipient = new IBinder.DeathRecipient(){
@override
public void binderDied(){
if(iBookManager == null){
return;
}
iBookManager.asBinder().unlinkToDeath(recipient,0);
iBookManager = null;
//这里从新绑定远程Service
}
};
复制代码
其次,在客户端绑定远程服务成功以后,给Binder设置死亡代理
@Override
public void onServiceConnected(ComponentName name, IBinder binder) {
iBookManager = IBookManager.Stub.asInterface(binder);
binder.linkToDeath(recipient,0);
}
复制代码
//authority与表名关联,根据传入的URI取出来外界想要操做哪张表
//content://com.icbc.im.provider/user
//content://com.icbc.im.provider/book
UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(authority, path, code);
uriMatcher.addURI(authority, path, code);
复制代码
getContext().getContentResolver().notifyChange(uri, null);
复制代码
外界注册数据改变监听
getContext().getContentResolver().registerContentObserver(uri,true,new ContentObserver(null) {
@Override
public void onChange(boolean selfChange, Uri uri) {
super.onChange(selfChange, uri);
}
});
//解除注册
getContext().getContentResolver().unregisterContentObserver()复制代码