美文网首页
Android IPC机制

Android IPC机制

作者: 在下陈小村 | 来源:发表于2019-08-08 22:32 被阅读0次

    什么是IPC,inter_process Communication的缩写,说人话:进程间通信。

    三个问题:
    1.进程和线程有什么区别,是什么关系。
    2.为什么要采用多进程,在什么情况下用。
    3.Android中有哪些进程间通信的方式。

    第一个问题:
    线程是CPU调度的最小单元,是一种有限的系统资源,而进程指执行单元,一个程序或者一个应用。一个进程能够包含多个线程。
    扩展:在Android里面只有主线程也就是UI线程可以操作界面元素。耗时的操作比如网络下载放在主线程操作的话,可能引起ANR异常,即应用无响应。所以耗时操作需要另起线程。

    第二个问题:
    一是自身某些原因需要,比如某些模块需要单独的进程,二是是要从其他程序里边获取数据,比如拿通讯录数据。

    第三个问题:
    bundle、文件共享、AIDL、Messenger、ContentProvider、Socket、binder

    进程的其他知识点
    1.Android中一个应用开启多进程只能是给四大组件在注册时加上android:process属性,“:remote”表示当前进程的私有进程,不能和其他应用的组件跑在一起,而不以:开头的进程,表示全局进程,其他应用可以通过ShareUID和他跑在一起。
    2.Android系统会为每个应用分配一个UID,当ShareUID和包名都相同的情况下,才可以跑在同一个进程当中,这时他们就相当于一个应用的两个部分,能够共享内存和数据。
    3.通过给一个应用创建多个进程,然后应用中包含一个带有静态变量的实体类,再通过某一个进程为这个实体类的静态变量修改值,最后分别在这三个进程中打印实体类的静态变量的值。结果发现静态变量的值只在被改变的进程当中有效,其他进程中保持初始值。由此可以得出Android为每个进程都分配了一个独立的虚拟机,不同虚拟机在内存分配上有不同的地址空间,这就导致在不同的虚拟机访问同一个类的对象会产生很多副本。这就导致不同进程之间不能通过内存来共享数据。具体表现如下
    (1)静态成员和单例模式完全失效
    (2)线程同步机制完全失效
    (3)SharePreferences的可靠性下降
    (4)Application会被多次创建
    关于ShareUID可以看一下## Android ShareUserId 使用总结

    IPC的基础知识
    为了更好的了解IPC的知识,就必须了解序列化和反序列化的知识(Serializable和Parcelable),以及Binder。

    Serializable接口
    这是一个Java提供序列化的接口,serialVersionUID,是序列化和反序列化的一个标识码,系统会根据类结构生成一个serialVersionUID,当类添加或者删除了成员变量,那么serialVersionUID值就会发生变化,这将导致之前序列化好的文件再进行反序列化时报错,所以最好手动指定一个serialVersionUID。

    Parcelable接口
    专门为Android设计的一个序列化接口,相对于Serializable,使用起来会复杂一点,但是效率更高。

    Binder


    image.png
    image.png

    进程间通信的几种方式
    (1)Bundle
    启动另一个进程的四大组件,通过Intent传递附加在Bundle里面的数据。这个是最简单的进程间通信。
    (2)使用文件共享
    就是在一个进程中把数据序列化写入文件中,然后在另一个进程中反序列化。需要注意的是Android中并发读写可能会导致数据的错误。所以这种方式最好是在低并发的情况下使用。
    (3)Messenger
    说白了就是使用Messenger携带Bundle数据,然后MessengerHandler读取数据,服务端和客户端相互绑定以后,相互发送数据,其底层实现就是AIDL。
    (4)AIDL
    1.服务端
    服务端创建一个service来监听客户端的连接请求,然后创建一个AIDL文件,将暴露给客户端的接口在这个AIDL文件中声明,最后在Service中实现这个AIDL接口。
    2.客户端
    绑定服务端的接口,将绑定成功后的Binder对象转换成AIDL接口所属的类型,然后调用AIDL的方法。
    3.AIDL文件的创建
    AIDL支持的数据类型,包括基本数据类型(int,double,long,char,boolean),String和CharSequence,List只支持ArrayList里面每个元素都必须被AIDL支持,Map和List一样,所有实现了Parcelable接口的对象,所有的AIDL接口本身也可以在AIDL中使用。
    自定义的Parcelable对象和AIDL对象都必须显示的import,并且必须放在同一个包内。除了基本的数据类型,其他类型的参数必须标上in、out、inout方向。AIDL只支持方法不支持静态常量。所有的AIDL文件最好统一放在一个文件夹里面,AIDL的包结构在服务端和客户端都必须保持一致。
    4.Service的实现
    创建一个实现AIDL方法的Binder对象,然后在onBinder里面返回。
    5.客户端实现
    在绑定时转换成AIDL对象,然后调用
    6.解绑时因为Binder对象在传递过程中被变换了,所以要用RemoteCalBackList来解绑。

    注意线程操作,因为AIDL是耗时操作。另外可以给我们的AIDL加上权限。
    (5)ContentProvider
    直接通过封装的CRUD方法实现数据交互。
    (6)Scoket
    通过scoket网络请求相互通信。

    Binder连接池
    就是为了有多个AIDL接口的时候方便统一管理,只要写一个service然后加一个Binder连接池就能统一管理。

    image.png

    相关文章

      网友评论

          本文标题:Android IPC机制

          本文链接:https://www.haomeiwen.com/subject/ihokdctx.html