2.1 AndroidIPC
IPC是intent-process-Communication的缩写,跨进程通信或进程间通信。进程和线程是两种不同的概念,线程是cpu调度最小的单元,也是一种有限的系统资源。而进程一般指一个执行单元,在PC和移动设备上指一个程序或者是一个应用。
Android系统会为每个应用分配一个唯一一个的UID,具有相同的UID才能共享数据,两个应用通过ShareUID泡在同一个进程是有要求的,需要两个应用具有相同的ShareUID并且签名相同才可以。
Android系统为每一个应用分配一个独立的虚拟机,或者说为每个进程都分配了一个独立的虚拟机,不同的虚拟机在内存分配上有不同的地址空间,这就导致不同的虚拟机访同一个类的对象会产生多份副本,不同副本之间互不干扰。在其中一个进程中修改同一个类的数据只会影响当前进程,对其他进程不会造成影响。
所有运行在不同进程中的四大组件,只要它们之间需要共享内存来共享数据,都会共享失败,这也是多进程所带来的主要影响。
使用多进程会造成的问题:
1 静态成员和单例模式完全失效。
2 线程同步机制完全失效。
3 SharePeferences的可靠性下降。
4 application会多次创建。
1和2 问题类似,不能共享内存,不是同一个对象,对象的成员都不一样,不管是所对象还是锁全局类都无法保证线程同步,因为不同进程锁的不是同一个对象。 3 因为SharePeferences不支持两个进程同时执行写操作,否则会导致一定几率数据丢失,这是因为SharePeferences底层是通过读写XML来实现的。4 当一个组件跑在一个新的进程时,系统要在创建新的进程同时分配独立的虚拟机,所以这个过程其实就是启动一个应用的过程。相当于系统又把这个应用重新启动了一遍。又重新启动的话,自然会重新创建新的application。运行在同一个进程的组件属于同一个虚拟机和同一个application的。
2.1.1 IPC基础概念介绍
实现跨进程通信方法: intent数据传递,共享文件,SharedPreferences,基于Binder的Messager和AIDL以及Socket等。更好地理解各种IPC方式,需要先熟悉一些基础概念,比如序列化相关的Serializable和Pacelable接口,以及Binder概念。
当我们需要通过Intent和Binder传递数据时需要用到Serializable和Parcelable,还有的时候我们需要将对象持久化的存储在设备上或者通过网络传输给其他的客户端,这个时候需要Serializable来完成对象的序列化。
Serializable采用ObjectOutputStream和ObjectInputStream就可实现序列化和反序列化操作。
Parcelable由writeToParcel,通过Parcel中的一系列write方法来完成序列化过程。 由CREATOR来完成反序列化,其内部表明如何创建序列化对象和序列化数组。并通过Parcel的一系列read方法来完成反序列化过程。内容描述功能是由discrebeContents方法来完成,几乎所有情况下这个方法的返回值都是0,仅当当前对象中存在文件描述此方法返回1。
Serializable是java中的序列化接口,使用过程中开销很大,序列化和反序列化过程需要大量IO操作。Parcelable是Android中的序列化方式,使用比较麻烦,但是效率很高。Parceble主要用于内存序列化上。
2.1.2 Binder
Binder是Android的一个类,它实现了IBinder接口。
从IPC角度来看,Binder是一种跨进程的通信方式,也可以理解为一种物理设备,它的设备驱动是/dev/binder;从Android Framework角度来说,Binder是ServerManager连接各种Manager(WindowManager,ActivityManager)和相应的ManagerService的桥梁;从Android应用层来看,Binder是客户端和服务端进行通信的媒介,当binderServeiced的时候,服务端会返回一个包含服务端业务调用的Binder对象,通过这个Binder对象可以获取服务端提供的服务和数据。