Binder 是什么?
安卓中的一种IPC的通信机制,了解他的思想,也是贯穿framework源代码很多地方,能够帮助我们更好的理解源代码。他的架构是c/s 架构
AMS 和 ActivityThread 用到Binder通信机制
Binder机制支持匿名,相对安全。
什么时候要用进程间通信?
开发中WebView的访问,还有图片的加载,推送,双进程守护,下载,闹钟服务,摄像头,电话。
像支付宝等这些大型应用用的比较多,还有银行类的app
为什么要多进程?
可以多进程进行应用保护存活
cpu 分配给每个应用进程是有限制的,单个进程过多的消耗会导致OOM
进程间通信为什么用到Binder机制?
内存划分,分为用户空间和内核控件。
进程之间的数据是隔离的。
每个进程有一个自己的用户空间。
进程之间需要通过内核进行通信。
性能: Binder 只需要拷贝一次
特点:C/S 架构相对简单易用
安全:支持匿名,相对安全
IPC 传统通信:
如图,CopyFrom,CopyTo 传输机制拷贝了两次
Binder 在内核和进程存在一个内存映射,mmap。只有在发送数据的时候copy一次数据,获取直接在内存映射获取数据


AIDL 安卓接口定义语言
github 项目模拟 https://github.com/zcwfeng/zcw_android_demo
Service
Client 项目中的AidlClient
客户端如何获取AIDL遥控器的
IZcwAidl.Stub.asInterface---调用这个Stub.asInterface 方法
我们定义生成aidl文件的时候系统帮助我们生成了
public interface IZcwAidl extends android.os.IInterface
-> class Default 用来定义我们数据的传输
-> abstract class Stub
-> asInterface()
-> onTransact()
-> class Proxy 数据相关的业务
public static abstract class Stub extends android.os.Binder implements top.zcwfeng.aidl.IZcwAidl
通过这个遥控器是如何调用到服务端的呢?
服务端又是如何处理的呢

如果还不够清晰,可以看使用aidl后as帮助我们生成的结构
实际上Binder是个代理设计模式,属于远程代理
新建AIDL文件,
测试方法 addPerson(person) & List<Person> getPersonList()
执行过程 addPerson 为例
client
// 获取AIDL的方法
IZcwAidl.Stub.asInterface(service)
客户端:
调用
aidl?.addPerson(Person("zcw", 2))
Proxy 里面的方法 实现AIDL接口方法
android.os.Parcel _data = android.os.Parcel.obtain(); _data ---- Client 用到了这个
android.os.Parcel _reply = android.os.Parcel.obtain(); _reply ----服务端返回的数据
addPerson ->
mRemote.transact(Stub.TRANSACTION_addPerson, _data, _reply, 0);
-> 到了Binder 进行处理
服务端:
onTransact 接收处理
case TRANSACTION_addPerson:
{
data.enforceInterface(descriptor);
top.zcwfeng.aidl.Person _arg0;
if ((0!=data.readInt())) {
_arg0 = top.zcwfeng.aidl.Person.CREATOR.createFromParcel(data);
}
else {
_arg0 = null;
}
this.addPerson(_arg0);
reply.writeNoException();
return true;
}

整个过程就是:
client:addPerson-> Proxy ------>mRomote:transact()-----Binder-------onTransact()------->Service:addPerson->Stub
各种通信机制进行了对比

Framework 服务原理分析
我们通常使用服务会用getSystemService(Context)
我们自己实现需要自己实现android.os.Service处理
bindService(intent,conn, Context.BIND_AUTO_CREATE)
ContextImpl#bindServiceCommon()
我是api 29 ,发现Google 改来改去就是个坑,所以用23-26看源码吧
api 23
ContextImpl#bindServiceCommon()
ActivityManagerNative.getDefault().bindService
ActivityManagerNative.getDefault()--》Proxy.bindService
IActivityManager==IZcwAidl aidl 接口
ActivityManagerNative == Stub
ActivityManagerProxy == Proxy
bindService(app, token, service, resolvedType, conn, fl,
callingPackage, userId);===Service
ActivityManagerService === Service
ActivityManagerService#bindServiceLocked()
1.ActiveServices#bringUpServiceLocked()
2.ActiveServices#requestServiceBindingLocked(s, b.intent, callerFg, true);
1
// APP 已经创建了
app != null && app.thread != null
realStartServiceLocked(r, app, execInFg);
app.thread.scheduleCreateService()
//创建服务的方法
handleCreateService()
service = (Service) cl.loadClass(data.info.name).newInstance();--->ZcwAidlService
//APP没有创建
if (app == null)
2
//绑定与否
handleBindService();
IBinder binder = s.onBind(data.intent);===>iBinder
ActivityManagerNative.getDefault().publishService()===>AMS.publishService()
c.conn.connected(r.name, service);===>Client=>onServiceConnected()
IServiceConnection conn;
ConnectionRecord c
connection.onServiceConnected()
IServiceConnection===ServiceDispatcher.InnerConnection
29 变了,mmp的
----这里有待清晰描述----
ActivityManager.getService().bindIsolatedService
ActivityManager.getService()------>extends IActivityManager.Stub
IActivityManager--------->相当于Stub
mServices.bindServiceLocked
A进程访问B进程时的几种状态
-
进程B,整个进程都没有启动
-
进程B启动了,但是里面的Service没创建出来
-
进程B启动了,里面的Service也创建了,但是Service没有被绑定过,回调onBind()
-
进程B启动了,里面的Service也创建了,但是Service已经被绑定过,回调onRebind()
总结,记住这几种关系
AIDL 接口----->Stub抽象类------>Proxy类----->Stub的实现类
IZcwAidl----->Stub------>Proxy----->new IZcwAidl.Stub
IActivityManager---->ActivityManagerNative--->ActivityManagerProxy---->ActivityManagerService
网友评论