Android开发艺术探索 第2章 IPC机制 (概要)

 2.1 Android IPC 简介

1、IPC 是 Inter-Process Communication 的缩写,含义为  进程间通信 或者 跨进程通信,指 两个进程之间进行数据交换的过程。

2、操作系统描述:

1)线程是 CPU 调度的最小单元,同时  线程是 一种有限的 系统资源。

2)进程 一般 指一个执行单元,在 PC和移动设备上 指 一个程序或者 一个应用。

3)一个 进程 可以 包含多个 线程。因此 进程和线程是 包含与被包含的关系。

3、在 Android里面 主线程 也叫 UI线程,在 UI 线程中 才能操作 界面元素。

4、在Android中 有特色的 进程间通信方式 就是 Binder;Android 还支持 Socket,通过Socket 也可以实现 任意两个终端之间的通信,一个 设备上 两个进程通过 Socket 通信也是可以的。


2.2 Android 中多进程模式

2.2.1  开启多进程模式

1、开启多线程方法:

1)常规方法: 给 四大组件(Activity、Service、Receiver、ContentProvider) 在AndroidMenifest 中 指定 android:process属性。

2)非常归方法:通过JNI 在native层 去 fork 一个新的 进程。(属特殊情况,也不是 常用的创建多进程的方式)

2、示例:


1)可以用 shell 命令 查看 进程信息。

adb shell  ps 或者 adb shell ps|grep 包名(利 com.ryg.chapter_2)

3、android:process=":remote"

    android:process="com.ryg.chapter_2:remote"

两种方式区别:

① 进程以":"开头,默认前面附加上 当前的包名;属于 当前应用的 私有进程,其他的应用组件 不可以 和它 跑在  同一个进程中。

②进程不以":"开头,是一种 完整 的命名方式,不附加包名信息; 属于 全局进程,其他应用 通过  ShareUID 方式 可以和 它 跑在同一个进程中。

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

两个应用通过 ShareUID 跑在同一个进程中  要求:两个应用 有 相同的 ShareUID并且 签名相同。

可以互相访问对方的私有数据,比如data目录,组件信息等,不管是否跑在同一进程中。

如果在同一进程,还可以 共享 内存数据。 【他们看起来  就像是 一个应用 的两个部分】

2.2.2  多进程模式的运行机制

1、Android为 每一个应用分配了一个独立的虚拟机,或者说  为每个进程 都分配 一个独立的虚拟机,不同的虚拟机 在内存 分配上有不同的地址空间, 导致 在 不同的虚拟机中 访问 同一个类 的对象 会 产生 多份副本。【在一个进程中 修改某个值,只会影响当前进程,对其他进程不会造成任何影响。】

2、使用 多进程 造成的问题:

1)静态成员 和 单例模式 完全失效;

2)线程同步机制 完全失效;

3)SharePreferences 的可靠性 下降;【原因: SharePreferences 不支持两个进程 同时 去执行 写操作----SharePreferences 底层 是通过 读/写 XML文件 来实现,并发写 可能出现问题】

4)Application 会多次创建。【不同进程的组件 拥有独立的 虚拟机、 Application】

3、跨进程通信 实现 数据交互

1)通过 Intent 来传递数据;

2)共享文件 和 SharePreferences;

3)基于 Binder 的 Messenger和AIDL;

4)Socket等。


2.3 IPC基础概念介绍

2.3.1  Serializable接口

Serializable 是Java 提供的 一个 序列化接口,一个空接口,为 对象 提供 标准的 序列化 和 反序列化操作。

1)使用方式:  在类中 声明 标识,如下所示。

private static final long serialVersionUID=xxxxxxxL;

PS:

① serialVersionUID不是必须,不声明仍可以实现 序列化,但是会对  反序列化过程产生影响(?)

② serialVersionUID 是用来 辅助 序列化和 反序列化过程的,原则上 序列化后 的数据中 的serialVersionUID 只有 和当前类的 serialVersionUID 相同才能够 正常的被反序列化。

③ serialVersionUID的详细工作机制:

序列化的时候,系统会把当前类的 serialVersionUID 写入序列化的文件(也可能是其他中介)中,当 反序列化的时候,系统会去检测 文件中 的serialVersionUID,看他是否和当前类的 serialVersionUID 一直,如果一致,说明 序列化的类的版本 和当前类的版本是相同的,可以成功反序列化,否则无法正常反序列化。

④ 重点注意:首先静态成员变量属于类不属于对象,所以不会参与序列化过程;其次用 transient关键字标记的成员变量不参与序列化过程。

⑤方法:

private void writeObject(java.io.ObjectOutputStream out) throws IOException{

//write 'this' to 'out' ...

}

private void readObject(java.io.ObjectInputStream out) throws IOException,ClassNotFoundException{

//populate the fields of 'this' from the data in 'in' ...

}

2.3.2  Parcelable接口

1)是Android 中提供新的序列化方式。【一个类的对象就可以实现序列化并可以通过Intent和Binder传递】

2)三大过程:序列化,反序列化,内容描述。

①序列化:writeToParcel方法完成,最终是 通过 Parcel中的一系列 write 方法来完成。

②反序列化:由CREATOR来完成,其内部表明了如何创建序列化对象和数组,并通过Parcel的一系列read方法来完成反序列化过程;

③内容秒速:describeContents方法完成;几乎在所有情况下这个方法都应该返回0,仅当当前对象中存在文件描述符时,此方法返回1。

3)Parcelable、Serializable 如何选取?

①Serializable 是Java中的序列化接口,用起来简单但是 开销很大,徐泪花和反序列化过程 需要大量 I/O操作。

②Parcelable数 Android中的序列化方式,更适合在Android平台上。缺点是 使用起来稍微麻烦点,但是效率很高,是Android推荐的序列化方式。【首选Pracel】

③将对象序列化到存储设备中 或者 将对象 序列化后通过 网络传输时 ,建议使用 Serializable【Pracel 也是可以】

【后续追加】









你可能感兴趣的:(Android)