Android AIDL 详解

本文详细解析了Android中进程间通信(IPC)的基本原理与实现方法,包括多进程的使用场景、开启方式及其带来的问题。介绍了序列化(Serializable)与AIDL在IPC中的作用,以及如何通过Binder机制进行跨进程调用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值