Android AIDL 详解

411 阅读2分钟

简介

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