首先说一下android 进程间通信的几种方式:内存共享、管道、消息队列、socket、binder 其实质都是运用内核空间的一块内存只是方式不同 ,系统服务在单独的进程中 每个进程都有自己的上下文和looper机制,android系统分层 为了安全、稳定(进程互不影响) 以及内存管理一个app进程占用一定的内存 如果需要增加app内存 多进程实现浏览手机照片 卡顿 (内存不够)推送独立进程 方便消息不丢失
内存共享:多个进程共享内存(通过页表 多个进程指向同一个内存)这种通信 直接改变内存的信息不需要复制内容,效率最高没有同步机制(手动限制访问)没有安全性可言
管道:管道(进程A写段,进程B读段)分为命名管道、无名管道,需要管道文件(中介) 数据经过两次复制 会出现阻塞,有限缓冲区 写入和读出 都需要约定好数据格式
消息队列:存放在内核中的消息链表双方要约定好类型
socket:网络通信,CS模式 两个缓冲区 一读一写 一次通信 两次拷贝 存在安全问题
binder:MMap 内存映射 s端 有一块物理空间与用户物理空间有一片地址 一一相对 内核空间也有一块与用户物理空间一一对应c发送数据到内核空间(一次数据拷贝)实际到内存映射空间可以添加权限(uid)数据大小(1M-8k)
binder通信模型:内存划分(用户空间---》(系统调用)内核空间)即app--->framework-->(JNI+BInder)native-->内核
binder是什么时候创建的?进程创建的时候 就准备了binder
server注册binder到servicemanager -》client拿到serverbinder -》通信
AMS自己注册到ServiceManager表里面的 (binder驱动去通信)
system server进程 main()-》启动ams服务 startService(反射)--》ActivityTaskManager
(onstart)创建 publishBinderService--》addService(保存ams)
binder初始化本质是初始化binder驱动(main函数 ),每次binder通信都会创建一个线程
AIDL
java和native通信才可以生成c++文件(sdk/build_tools/aidl.exe)
aidl自动生成的文件:stub(电影票存根)代表服务
client-》proxy-》binder驱动-》Stub==service proxy代理的stub 给client用
1、客户端进程与ServiceManager通信获得AMS的IBinder
activity.bindService实际是父类contextImpl的 startServiceCommond-》AMS.bindIsolateService->bindServiceLock
asInterface把服务转换为对应的proxy
bindService过程
activity 通过ServiceManager.getService()拿到AMS的IBinder 然后调用ams.binService()->ams.scheduleBindService建立连接,service通过ServiceManager.getService()拿到AMS的IBinder然后调用ams.publishService()把service的IBinder传给ams-->c.conn.connected回调给Activity
client端
serviceManagerProxy(stub.proxy)->IserviceManager.Stub.Proxy.getService()->
BinderProxy.transact()->android_util_binder.android_os_BinderProxy_transact()
->BpBinder.transact()
ServiceManager:一个独立进程(init创建 早于zygote 在init.rc文件里配置的)挂了 系统会重启 允许传递数据大小1M-8k
main()->new ServiceManager()(实质是BBinder的子类)
->setTheContextObject(manager)设置服务端BBinder->监听驱动文件变化
aidl java层提供服务 得暴露继承stub的类 ,serviceManager提供服务得暴露BNServiceManager
IPCThreadState 传递数据的作用
service端
驱动iontl->looperCallBack(BinderCallBack)->IPCThreadState ::self()->
handlePolledCommands()->BBinder(中转站)->transact->
BnServiceManager.onTransct()->ServiceManager.getService()