本文首发于个人博客 “胖蔡叨叨叨”,更多相关信息可点击查看《Android IPC机制》
IPC
IPC(Inter Process Communication) 进程间通信,是指系统中运行的不同进程间的信息交互过程。Android IPC通常用于应用间、或同应用不同进程间的数据通信。
IPC
常见的Android IPC通信方式如下:
- AIDL
- Messager
- ContentProvider
- Socket
- 文件共享
- Intent数据传递
IPC不是Androi所特有的,对于任一操作系统而言都有属于它的IPC机制,如windos的剪切板、管道等。对于Android来说,其本身是基于Linux内核实现的一款移动操作系统,但其IPC并未完全集成Linux操作系统,而是有其独特的进程间通信的方式Binder,Binder也是Android的一大核心机制。
多进程
Andorid 支持给应用开启多个进程,其实现方法很简单,只需要我们在清单配置文件Manifest.xml中给注册的四大组件添加进程配置属性:
...
<activity andorid:name=".MainActivity"
andorid:process=":remote"></activity>
...
需要注意的是,进程名以”:”开头的进程为当前应用的私有进程,其他应用不可与其运行在同一个京城中,而不是以”:”开头的进程属于全局进程,可通过shareUID方式与其他应用共享一个dalivk虚拟机(shareUId要求mainfest.xml配置相同的shareUId,并使用相同的签名)
多进程的烦恼
因为Android中会为每一个进程创建一个单独的虚拟机,不同的虚拟机的内存分配地址也不同,这就导致了不同进程的内存无法通过常规途径进行分享。会产生诸多如下类问题:
- 静态成员和单例模式失效
- 线程无法同步
- sharepreferences数据无法保证实时更新
- Appliction类会被多次创建
Serializable和Parcelable
在实现数据间传递的时候,我们会接触到数据的序列化。序列化是数据持久化存储、传输的基础实现,而Android则是通过Serializable和Parcelable接口来实现对象的序列化的。其中Serializable是java提供的而一个序列化接口,只需要我们实现这个序列化接口,并在类的声明中添加一个序列化标识即可。
public class User implements Serializable {
private static final long serialVersionUID = 127339249328490098;
public int id;
public String name;
....
}
User user = new User('hfcai',12);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("cache.txt"));
out.close(); // 通过ObjectOutputStream实现序列化过程
// 反序列化
ObjectInputStream in = new ObjectInputStream(new FileInputStream("cache.txt"));
User newUser = (User)in.readObject();
in.close;
Android自己也提供了一种序列化的接口Parcelable,通过实现Parcelable接口的实例对象,可通过Intent、Binder传递。
public class User implements Parcelable {
public int id;
public String name;
public Book book;
public User(String name,int id){
this.name = name;
this.id = id;
}
public int describeContents(){
return 0;
}
public void writeToParce(Parcel out,int flags){
out.writeInt(id);
out.writeString(name);
out.writeParcelable(book,0);
}
public static final Parcelable.Creator<User> CREATOR = new Parcelable.Creator<User>(){
public User createFromParcel(parcel in){
return new User(in);
}
public User[] newArray(){
return new User[size];
}
};
private User(Parcel in){
id = in.readInt();
name = in.readString();
book = in.readParcelable(Thread.currentThread().getCOntextClassLoader());
}
}