要点提炼|Android开发艺术之IPC

要点摘要

 

 

一、IPC基础和概念

1、多进程模式

  1. IPC基础及概念
    • 多进程模式
    • 序列化
      • Serializable接口
      • Parcelable接口
    • Binder机制
  2. IPC方式
    • Bundle
    • 文件共享
    • AIDL
    • Messager
    • ContentProvider
    • Socket
  3. Binder连接池

a.进程&线程

  1. 进程:一般指一个执行单元,在PC和移动设备上指一个程序应用
  2. 线程:CPU调度的最小单元。线程是一种有限的系统资源。

两者关系: 一个进程可包含多个线程,即一个应用程序上可以同时执行多个任务。

  • 主线程(UI线程):UI操作
  • 有限个子线程:耗时操作

注意:不可在主线程做大量耗时操作,会导致ANR(应用无响应)。

 

 

b.开启多线程

 

 

  • (不常用)通过JNI在native层fork一个新的进程。
  • (常用)在AndroidMenifest中给四大组件指定属性android:process,进程名的命名规则:
    • 默认进程:没有指定该属性则运行在默认进程,其进程名就是包名
    • 以“:”开头的进程:
      • 省略包名,如android:process=":remote",表示进程名为com.example.myapplication:remote
      • 属于当前应用的私有进程,其他进程的组件不能和他跑在同一进程中。
    • 完整命名的进程:
      • android:process="com.example.myapplication.remote"
      • 属于全局进程,其他应用可以通过ShareUID方式和他跑在用一个进程中。

UID&ShareUID:

Android系统为每个应用分配一个唯一UID,具有相同UID的应用才能共享数据。

两个应用通过ShareUID跑在同一进程的条件:ShareUID相同且签名也相同。

  • 满足上述条件的两个应用,无论是否跑在同一进程,它们可共享data目录,组件信息。
  • 若跑在同一进程,它们除了可共享data目录、组件信息,还可共享内存数据。它们就像是一个应用的两个部分。

 

c.查看进程信息的方法

  • 通过DDMS视图查看进程信息。
  • 通过shell查看,命令为:adb shell ps|grep 包名

d.需要进程间通信的必要性

所有运行在不同进程的四大组件,只要它们之间需要通过内存在共享数据,都会共享失败。

原因:由于Android为每个应用分配了独立的虚拟机,不同的虚拟机在内存分配上有不同的地址空间,这会导致在不同的虚拟机中访问同一个类的对象会产生多份副本。

e.多进程造成的影响,总结为以下四方面:

 

①静态变量和单例模式失效。

           由独立的虚拟机造成。

②线程同步机制失效。

           原因同上。

③SharedPreference的不可靠下降。

            SharedPreferences不支持两个进程同时进行读写操作,即不支持并发读写,有一定几率导致数据丢失。

 

④Application多次创建。

           Android系统会为新的进程分配独立虚拟机,相当于系统又把这个应用重新启动了一次。


2.序列化

a.序列化的介绍

 

 

 

  • 含义:序列化表示将一个对象转换成可存储或可传输的状态。序列化后的对象可以在网络上进行传输,也可以存储到本地。
  • 场景:需要通过Intent和Binder等传输类对象就必须完成对象的序列化过程。
  • 两种方式:实现Serializable/Parcelable接口。

b.Serializable接口和Parcelable接口的比较:

要点提炼|Android开发艺术之IPC

c.serialVersionUID

含义:是Serializable接口中用来辅助序列化和反序列化过程。 注意:原则上序列化后的数据中的serialVersionUID要和当前类的serialVersionUID 相同才能正常的序列化。

注意:两种变量不会参与序列化过程:

  • 静态成员变量属于类,不属于对象。
  • transient关键字标记的成员变量。

二、IPC方式

1、使用Bundle

a.Bundle

支持在Activity、Service和Receiver之间通过Intent.putExtra()传递Bundle数据。

b.原理:Bundle实现Parcelable接口,它可方便的在不同的进程中传输。

c.注意:Bundle不支持的数据类型无法在进程中被传递。

思考下面这种情况:
Q:在A进程进行计算后的结果不是Bundle所支持的数据类型,该如何传给B进程?
A:将在A进程进行的计算过程转移到B进程中的一个Service( 比如IntentService )里去做,这样可成功避免进程间的通信问题。

2、使用文件共享

a.文件共享:两个进程通过读/写同一个文件来交换数据。比如A进程把数据写入文件,B进程通过读取这个文件来获取数据。

b.适用情况:对数据同步要求不高的进程之间进行通信,并且要妥善处理并发读/写的问题。

c.虽然SharedPreferences也是文件存储的一种,但不建议采用。

原因:系统对SharedPreferences的读/写有一定的缓存策略,即在内存中有一份该文件的缓存,因此在多进程模式下,其读/写会变得不可靠,甚至丢失数据。