Android跨进程通信

一 多进程之间的通信

由于不同进程所拥有的地址是两块不同的地址空间,所以不能直接通过共享内存共享数据了。

Linux常用跨进程通信方式:管道,信号量,共享内存,socket

Android常用跨进程通信方式:Intent ,共享文件,SharedPreferences,Binder,socket,基于Binder的Messenger.下面详细学习进程间的通信方式。

二,进程之间的通信方式

1.Binder

Binder是安卓中最重要的IPC通信方式了,一个应用进程的创建,应用进程中组件的生命周期的调度,系统服务的使用...处处都是binder,从而也可以看出,安卓中进程间的通信是非常频繁的,一句话来说,在Binder通信机制的强有力支持下,安卓进程间进行了友好的数据交互。


Binder是进程间通信的一种架构,这个架构分为:

  1. 服务端接口(Bn端)
  2. 客户端接口(Bp端)
  3. Binder驱动

 1.1  拆分xxx.aidl文件生成类
     由aidl生成的java文件(一个接口文件;该接口文件中嵌套一个抽象的类Stub,该类实现外边的接口文件,没有实现具体接口方法,接口方法由其子类实现;抽象类中有一个proxy类,该类是抽象Stub的代理类,同时也实现了最外层的接口文件,proxy文件的作用是将客户端的输入包装成统一形式,具体的业务实现在服务端 Stub的子类中)由aidl文件系统帮我们生成的三个文件,如下:

 a) 接口 IXXX extends IInterface

 b) abstract class Stub extends Binder imp IXXX    该类重写了binder的 OnTransact方法:

public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags){

.................

case TRANSACTION_startScan:
{
data.enforceInterface(DESCRIPTOR);  //校验
java.lang.String[] _arg0;
_arg0 = data.createStringArray(); //读取参数
com.miui.guardprovider.aidl.IVirusObserver _arg1;
_arg1 = com.miui.guardprovider.aidl.IVirusObserver.Stub.asInterface(data.readStrongBinder());//读取参数

boolean _arg2;
_arg2 = (0!=data.readInt());//读取参数
int _result = this.startScan(_arg0, _arg1, _arg2);//调用服务端具体实现函数
reply.writeNoException();
reply.writeInt(_result);//返回给客户端的结果
return true;
}
............................
}

 c) static class Proxy imp IXXX

     服务端的代理类,跨进程通信中,客户端使用代理类proxy调用服务

int startScan(java.lang.String[] paths, com.miui.guardprovider.aidl.IVirusObserver virusObserver, boolean isCloud) throws android.os.RemoteException

{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);//对应服务端data.enforceInterface(DESCRIPTOR)
_data.writeStringArray(paths);//写入参数
_data.writeStrongBinder((((virusObserver!=null))?(virusObserver.asBinder()):(null)));写入参数
_data.writeInt(((isCloud)?(1):(0)));写入参数
mRemote.transact(Stub.TRANSACTION_startScan, _data, _reply, 0);//调用服务端的方法
_reply.readException();
_result = _reply.readInt();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}

总结一个完整的通信过程:
    客户端进程得到Bp端引用,调用目标方法,目标方法中通过mRemote调用 transact()将目标函数的参数写入包裹,再通过底层binder驱动转发到服务端,经过OnTransact分发调用具体实现,最终调用到service中的具体业务实现。

 1.2 客户端如何获得服务端的Binder对象引用

    a)系统服务:使用getSystemService()方法获取的服务,系统服务一般不使用Service类实现,一般都是继承binder类。系统服务由ServiceManager来管理,系统服务在使用前向ServiceManager进行注册,客户端使用服务时向ServiceManager获取服务的引用。注意ServiceManager也是一个系统服务,它的代理架构跟其他系统服务一样的

    b)应用程序自定义服务:客户端服务则必须基于Service类来编写,通过bindService获取相关服务的binder引用,asInterface提供了统一的查询接口,如果IPC通信,返回Proxy对象引用,如果进程内部使用服务则返回 Stub的具体实现类对象引用。

 

     总结:两种获取方式最终都是通过AMS服务查询得到服务端的Binder引用

1.3 binder框架扮演的角色

   binder框架在整个通信过程中不做具体的业务实现,整个框架只负责运输数据,将客户端的请求精确传达给服务端,同时将服务端的处理结果传递给客户端。只做数据传输不做具体业务,从而满足快进程通信。

1.4 Framework层的binder架构与native层的binder架构之间的关系

 framework层的binder通过JNI调用native的binder架构,所以framework层(Java层)对native层(c/c++层)进行了一层包装,提供给应用层进行调用。native层binder是C/S架构,framework层的架构与相关类的设计原理与native层类似。所以理解了任意一层都很好理解另一层.

2.ContentProvider

2.1原理
ContentProvider底层实现是bin

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
千里马8年Android系统及应用开发经验,曾担任过美国unokiwi公司移动端技术总监兼架构师,对系统开发,性能优化,应用高级开发有深入的研究,Android开源定制ROM Lineage的贡献者之一,国内首家线下开辟培训Android Framework课程,拥有2年的Android系统培训经验。成为腾讯课堂专业负责android framework课程分享第一人,致力于提高国内android Framework水平Android Framework领域内是国内各大手机终端科技公司需要的人才,应用开发者都对Android系统充满着好奇,其中的binder是重中之重,都说无binder无Android,binde是Android系统的任督二脉。课程水平循序渐进,由中级再到高级,满足各个层次水平的android开发者。1、灵活使用binder进程通信,在app端对它的任何api方法等使用自如2、可以单独分析android系统源码中任何binder部分,分析再也没有难度3、掌握binder驱动本质原理,及对应binder驱动怎么进行进程通信,及内存等拷贝方式数据等4、对binder从上层的java app端一直到最底层的内核binder驱动,都可以顺利理通5、针对系统开发过程中遇到的binder报错等分析方法,及binder bug案例学习6、针对面试官任何的binder问题都可以对答自如7、socket这种进程通信实战使用8、针对android源码中使用的socket源码轻松掌握9、android系统源码中最常见的socketpair中双向进程通信10、使用socket实现一个可以让app执行shell命令的程序

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值