简介
IPC 是 Inter-Process Communication的缩写 使用多进程的原因: 1.有些模块必须用单独进程 2.Android对单个应用可使用的最大内存有限制,多一个APK可以申请更多的内存,早期的版本有16M
查看方法
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
int memClass = activityManager.getMemoryClass();//64,以m为单位
复制代码
开启多进程方式 AndroidMenifest 中指定 android:process
<activity
android:name=".SecondActivity"
android:label="@string/title_activity_second"
android:process=":remote" />
<activity
android:name=".ThirdActivity"
android:label="@string/title_activity_second"
android:process="com.example.ipc" />
复制代码
这里有两种声明进程的方式 第一种以“:” 开头的表示当前应用的私有进程,其他应用组建不可以和他跑在同一进程中 不以“:”开头的,其他应用可以通过ShareUID的方式跟他跑在同一进程中
多进程的问题:
1.静态成员和单例失效 2.Application多次创建 3.线程同步机制失效(不同进程里的不同线程操作的是不同的对象) 4.sharePreference可靠性下降(不支持两个进程同时执行写)
IPC 的一些基础概念
- Serializable
//序列化过程
PersonBean personBean = new PersonBean(1);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("cache.txt"));
out.writeObject(personBean);
out.close();
//反序列化过程
ObjectInputStream in = new ObjectInputStream(new FileInputStream("cache.txt"));
PersonBean newPerson = (PersonBean) in.readObject();
in.close();
复制代码
参数:serialVersionUID 序列化和反序列化时版本必须相同否则不成功 transient 关键字标识,不参与序列化
AIDL
asInteerface(andoird.os.IBinder obj)
用于将服务端Binder对象转换成客户端所需AIDL接口类型对象,是服务端进程返回Stub,否则返回Stub.Proxy对象
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.example.administrator.aidldemo.IBookManager))) {
return ((com.example.administrator.aidldemo.IBookManager)iin);
}
复制代码
这里根据TAG查询本地有没有这个接口,没有则是客户端进程
onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags)
这个方法运行在服务端Binder的线程池中,根据code 确定客户端调用的方法是什么 data取出方法需要的参数 reply 写入返回值 此方法返回false则客户端请求失败
Proxy#getBookList
@Override public java.util.List<com.example.administrator.aidldemo.Book> getBookList() throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
java.util.List<com.example.administrator.aidldemo.Book> _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_getBookList, _data, _reply, 0);
_reply.readException();
_result = _reply.createTypedArrayList(com.example.administrator.aidldemo.Book.CREATOR);
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
复制代码
此方法运行在客户端,当客户端调用此方法时,创建该方法所需要的输入类型Parcel对象 _data 和输出类型_reply 和返回值List 把参数写入data 然后调远程transact,同时当前线程挂起;直到服务端的结果返回时,当前线程继续执行;从reply中取出返回结果
linkToDeath和 unlinkToDeathd
当服务端由于某种原因异常终止时,客户端还不知道,Binder提供了两个方法,通过linkToDeath可以给binder设置死亡代理 当binder死亡时可以收到通知 binder