《Android开发艺术探索》读书笔记 (2) 第2章 IPC机制

来源:互联网 发布:淘宝解冻的金额在哪 编辑:程序博客网 时间:2024/05/17 21:42

前言

  • 在作为一个android新入门的菜鸟的时候,对于android进程内各组件之间通信就有点混淆不清了.更别说进程间通信和跨进程通信了.但随着项目的深入和经验的丰富,回过头来再看,会发现其实IPC机制也没有那么高深莫测,接下来就是我实际应用和读书笔记.

概念

  • IPC:Inter-Process Communication,表示进程间通信或者跨进程通信.是指两个进程之间进行数据交换的过程.
    (一般进程和线程的概念对于一个新手来说容易混淆)
  • 进程:一般指一个执行单元.例如:一个程序或者一个应用.一个进程可以包含多个线程,因此进程和线程是包含和被包含的关系.
  • 线程:是CPU调度的最小单元,线程也是一种有限的系统资源.

实现方式

  • 任何一个操作系统都需要有相应的IPC机制,Linux上可以通过命名通道\共享内存\信号量等来进行进程间通信.Android系统不仅可以使用Binder机制来实现IPC,还可以使用sockert实现任意两个终端间的通信.

    1.Android中多进程模式:

    实现方式主要有两种:

    1.在menifest中指定android:process属性就可以开启多进程模式.
    默认进程的进程名是包名packageName,
    私有进程–进程名以”:”开头的进程属于当前应用的,其他应用的组件不可以和它跑在同一个进程.

    全局进程–而进程名不以:开头的进程属于全局进程,其他应用通过ShareUID方法可以和它跑在同一个进程中.两个应用通过ShareUID跑在同一个进程中是有要求的,需要这两个应用有相同的ShareUID并且签名相同才可以.
    在这种情况下,它们可以相互访问对方的私有数据,比如data目录、组件信息等,不管它们是否跑在同一个进程中。如果它们跑在同一个进程中,还可以共享内存数据,它们看起来就像是一个应用的两个部分.

    2.通过JNI在native层去fork一个新的进程.

android:process=":abc" //进程名是 packageName:abcandroid:process="aaa.bbb.ccc" //进程名是 aaa.bbb.ccc
  • Android多进程模式的运行机制:android系统回味每个进程分配一个独立的虚拟机,不同的虚拟机在内存分配上游不同的地址空间,所以不同的虚拟机中访问同一个雷的对象会产生多个副本.因此多进程就会带来如下几个问题:
    1.静态成员和单例模式完全失效.
    2.线程同步机制完全失效,无论锁对象还是锁全局对象都无法保证线程同步.
    1. SharedPreferences的可靠性下降,SharedPreferences不支持并发读写.
    2. Application会多次创建:当一个组件跑在一个新的进程的时候,系统要在创建新的进程的同时分配独立的虚拟机,应用会重新启动一次,也就会创建新的Application。
      运行在同一个进程中的组件是属于同一个虚拟机和同一个Application。
      同一个应用的不同组件,如果它们运行在不同进程中,那么和它们分别属于两个应用没有本质区别。

IPC基础概念介绍

  1. Serializable接口:Java中为对象提供标准的序列化和反序列化操作的接口,用于存储设备或网络传输,完成对象的持久化.
    实现方式:
    1.implement serializable接口
    2.指定serialVersionUID,例如:1L
    serialVersionUId是一串long型数字,主要是用来辅助序列化和反序列化的,原则上序列化后的数据中的serialVersionUId只有和当前类的serialVersionUId相同才能够正常地被反序列化。
    serialVersionUId的详细工作机制:序列化的时候系统会把当前类的serialVersionUId写入序列化的文件中,当反序列化的时候系统会去检测文件中的serialVersionUId,看它是否和当前类的serialVersionUId一致,如果一致就说明序列化的类的版本和当前类的版本是相同的,这个时候可以成功反序列化;否则说明版本不一致无法正常反序列化。一般来说,我们应该手动指定serialVersionUId的值。

    注意:1.静态成员变量不会参与序列化过程;2.用transient关键字标记的成员变量不参与序列化过程

  2. Parcelable接口:只要实现这个接口,一个类的对象就可以实现序列化并可以通过Intent和Binder传递.
    Parcelable主要用在内存序列化上,可以直接序列化的有Intent、Bundle、Bitmap以及List和Map等等

  3. Serializable和Parcelable区别:
    1.Serializable虽使用简单,但是开销很大,序列化和反序列化的过程需要大量I/O操作
    2.Parcelable使用稍微麻烦点,但是它的效率很高
    3.网络传输对象还是首选Serializable

  4. Binder:
    概念:Binder是Android中的一个类,他实现了IBinder接口.
    Binder是Android中一种跨进程通信的方式.
    Binder还可以理解为虚拟的物理设备,它的设备驱动是/dev/binder;
    从Framework层角度看,Binder是ServiceManager连接各种Manager和相应的ManagerService的桥梁;
    Binder是客户端和服务端进行通信的媒介,当bindService的时候,服务端会返回一个包含了服务端业务调用的Binder对象,通过这个Binder对象,客户端就可以获取服务端提供的服务或者数据,这里的服务包括普通服务和基于AIDL的服务。
    注:在Android开发中,Binder主要用在Service中,包括AIDL和Messenger,其中普通Service中的Binder不涉及进程间通信,较为简单;而Messenger的底层其实是AIDL,正是Binder的核心工作机制。

Android中的IPC方式

  1. **使用Bundle:**Bundle实现了Parcelable接口,Activity、Service和Receiver都支持在Intent中传递Bundle数据。

  2. 使用文件共享:这种方式简单,适合在对数据同步要求不高的进程之间进行通信,并且要妥善处理并发读写的问题。
    如果出现并发读写的操作,建议使用线程同步来限制多个线程的写操作.
    当然,文件共享这种方式,不建议使用SharedPreferences在进程间通信中使用.

  3. 使用Messenger:*Messenger是一种轻量级的IPC方案,它的底层实现就是AIDL。使用方式有点类似message*.Messenger是以串行的方式处理请求的,即服务端只能一个个处理,不存在并发执行的情形,详细的示例见原书。P66案例.

  4. 使用AIDL:大致流程:首先建一个Service和一个AIDL接口,接着创建一个类继承自AIDL接口中的Stub类并实现Stub类中的抽象方法,在Service的onBind方法中返回这个类的对象,然后客户端就可以绑定服务端Service,建立连接后就可以访问远程服务端的方法了。最后会有一个demo源码附上.
    1.AIDL支持的数据类型:基本数据类型、String和CharSequence、ArrayList、HashMap、Parcelable以及AIDL;
    2.AIDL接口中支持方法,不支持声明静态变量;
    3.为了方便AIDL的开发,建议把所有和AIDL相关的类和文件全部放入同一个包中,这样做的好处是,当客户端是另一个应用的时候,可以直接把整个包复制到客户端工程中.

  5. 使用ContentProvider:
    1.ContentProvider主要以表格的形式来组织数据,并且可以包含多个表;
    2.ContentProvider还支持文件数据,比如图片、视频等,系统提供的MediaStore就是文件类型的ContentProvider;
    3.ContentProvider对底层的数据存储方式没有任何要求,可以是SQLite、文件,甚至是内存中的一个对象都行;
    4.要观察ContentProvider中的数据变化情况,可以通过ContentResolver的registerContentObserver方法来注册观察者;

6.使用Socket:
Socket是网络通信中“套接字”的概念,分为流式套接字和用户数据包套接字两种,分别对应网络的传输控制层的TCP和UDP协议。
TCP协议:是面向连接协议,提供稳定的双向通信的功能;
UDP协议:是无连接的,提供不稳定的单向通信功能,也可以实现双向通信.UDP具有更好的效率,但不保证数据一定正确传输
7.Binder连接池
项目多个模块都需要使用AIDL来进行进程间通信,使用Binder连接池来进行管理;
作用:将每个业务模块的Binder请求统一转发到远程Service中去执行,避免重复创建service;

总结

这里写图片描述

参考资料

http://hujiaweibujidao.github.io/blog/2015/12/05/Art-of-Android-Development-Reading-Notes-2/这里写链接内容

源码下载

  • 使用AIDL跨线程通信demo下载.http://download.csdn.net/detail/qq_28690547/9424117
1 0
原创粉丝点击