1. 通过android:process开启新的进程
进程名以“:”开头的属于当前应用的私有进程,其他应用的组件不可以和它跑在同一个进程中,
不以冒号开头的为全局进程,其他应用可以通过ShareUID方式可以和它跑在同一个进程中。要求ShareUID相同且签名相同,可以访问对方的私有数据,如data目录、组建信息等。同一个应用的多进程,相当于两个不同的应用采用了ShareUID的模式。
2. Serializable接口
配合serialVersionUID使用,自动序列化和反序列化;静态成员和transient关键字成员不参加序列化过程;
3. Parcelable接口
实现Parcelable接口,即实现writeToParcel(Parcel out, int flags)和Parcel.Creator中的createFromParcel;
4. Binder
可以理解为一种虚拟的物理设备,驱动是/dev/binder,通过ServiceManager连接AMS、WMS;
客户端发起请求时,当前线程会被挂起直到服务器端进程返回数据,所以耗时的远程方法不能在UI线程中调用;服务端的Binder运行在Binder的线程池中,所以不管是否耗时都应该采用同步的方式实现;
5. 手动实现一个Binder的步骤:
1)继承IInterface接口IXXXXInterface,加入业务方法和方法id,DESCRIPTOR;
2)创建Stub类,即继承Binder并实现IXXXXInterface接口,在Service的onBind方法中返回该对象
3)创建Proxy类,即实现IXXXXInterface,内涵IBinder类型的mRemote对象
4)linkToDeath可以在Binder死亡时收到通知,重新绑定远程Service
6. SharePreferences
通过键值对存储数据,底层采用XML,保存在/data/data/package name/shared prefs目录下,不建议在多进程中使用。
7. Messenger
服务端创建一个Service来处理客户端请求,同时创建一个Handler并通过它来创建一个Messenger对象,然后在Service的onBind中返回这个Messager对象底层的Binder即可。
客户端首先绑定服务端Service,之后用服务端返回的IBinder创建一个Messenger发送Message来与服务器通信;
客户端还可以创建一个新的Messenger并把它通过Message的replyTo参数传递给服务器,服务端通过replyTo可以和客户端通信。
Message中能使用的载体只有what, arg1, arg2, Bundle以及replyTo,自定义的Parcelable对象在Message的object字段无法跨进程传递。
Messager是以串行方式处理客户端发来的消息,如果大量的消息同时发送到服务端,服务端只能一个个处理;
8. AIDL
建议把所有和AIDl相关的类和文件全部放倒同一个包中,当客户端是另一个应用时可以直接把整个包复制到客户端工程中,使得包结构保持一致;
CopyOnWriteArrayList和ConcurrentHashMap支持并发读写,AtomicBoolean原子变量,
1)服务端创建Service监听客户端的连接请求,创建AIDL文件并实现相关方法;
2)客户端绑定Service,通过返回的IBinder调用AIDL定义的相关方法;
3)客户端实现一个IXXXXInterface.Stub类,生成本地Binder,然后传到Service端,Service端回调这个客户端Stub类的相应方法,客户端用Handler将回调方法转到主线程中处理
4)使用RemoteCallbackList来删除跨进程listener的接口,RemoteCallbackList
5)客户端的onServiceConnected和onServiceDisconnedted方法都在UI线程中,服务端运行在Binder线程中;
6)服务端进程意外停止,可以给Binder设置DeathRecipient监听,收到binderDied回调(Binder线程)重连远程服务,或者在onServiceDisconnected中(UI线程)重连;
9. AIDL的权限验证
1)在AndroidMenifest中声明所需权限
在Service的onBind方法直接返回(Stub)mBinder之前调用checkCallingOrSelfPermission("com.aaa.bbb.permission.ACCESS_BOOK_SERVICE"),
内部应用想绑定到Service中,
2)在服务器端的onTransact方法中进行验证,可采用权限或者Uid和Pid,获取包名。
覆盖onTransact,调用checkCallingOrSelfPermission验证权限,调用getPackageManager().getPackagesForUid(getCallingUid())获得包名;
3)通过android:permission验证
10. ContentProvider
11. 使用Socket
1)权限声明
不能在主线程访问网络
2)当Service启动时,会在线程中建立TCP服务(ServerSocket),监听8868端口,然后等待客户端的连接请求。客户端连接后会生成一个新的Socket(调用ServerSocket.accept()创建),并开启新线程处理不同的客户端请求(BufferedReader读,PrintWriter写)。客户端断开时服务端会关闭相应的Socket(因为客户端断开后,服务端的输入流回返回null)。
3)客户端在自线程中创建Socket连接8688端口,在while循环中读取服务器端消息;
12.Binder连接池,将所有的AIDL放在同一个Service中处理
1)定义一个AIDL接口IBinderPool,里面有个IBinder queryBinder(int binderCode)方法,根据不同的binderCode,返回不同的Stub的实现类的binder本地对象,这些实现类分别实现了自己的AIDL接口方法;
2)Service端创建IBinderPool的本地对象,在onBind中返回;
3)客户端实现一个BinderPool单例类,调用bindService获取IBinderPool,然后提供queryBinder(int binderCode),内部调用IBinderPool的queryBinder方法;
4)客户端的Activity在自线程中调用BinderPool的queryBinder,因为BinderPool中用了CountDownLatch,将异步操作转成了同步操作。