带你了解Android IPC机制(上集)
1.IPC简介
首先,什么是IPC? 听起来好像有点高大上的感觉,其含义实际是进程间通信或跨进程通信,是指两个进程之间进行数据交换的过程。 如果这样说还不太理解,我们可以理解为,两个app之间的通信,首先两个app之间的通信肯定不能通过线程,所以提出IPC机制,解决多进程通信的问题。既然说的是进程间通信,我们必须要知道什么是进程,他和线程的区别是什么?
进程是资源分配的最小单位,线程是CPU调度的最小单位。进程有独立的内存地址,而线程没有。一个进程可以包含一个或多个线程。
IPC机制并不是Android独有的,我们常用的Windows操作系统linux操作系统中,复制粘贴
也是IPC机制的一种实现。除此之外,Windows常用的方法还有管道
和邮槽
来完成进程间通信。linux通过命名管道
,内存共享
,信号量
等进行进程间的通信。对于Android来说,实现进程间通信的方法有Binder
,Socket
。
2.如何开启多进程?
这个其实很简单,我们可以在配置清单中指定四大组件的一个属性
android:process=":romote"
android:process="com.ibuyi.free.remote"
这里我们讨论在一个app中的两个进程,对于多个app之间的进程其实原理也是相同的。
当我们的应用开启时,系统会用创建一个进程,进程名为完整的包名,如果我们使用
":remote"方式,省略完整包名,则系统会自动为我们添加上完整的包名。第二种就是直接指定完整包名的方法。这两种方式开启多线程略有不同。
区别:以“:”
开头的,是当前应用的私有进程,而不是以“:”
开头的是全局进程。
那么私有进程和全局进程又有什么区别呢?
如果进程是私有进程,则其他应用的组件不可以和它跑在同一个进程。如果是全局进程,可以通过shareUID方式和他跑在一个进程。如果这个不理解其实对下面的知识也没有影响。
3.多进程所带来的一些问题
- 静态成员和单例模式完全失效
- 线程同步机制完全失效
- SharedPreferences的可靠性下降
- Application会多次被创建
对于第一点,如果是两个进程之间,Android为每一个进程分配一个独立的虚拟机,试想,都不在同一块内存中了,一个虚拟机中的静态成员变量发生变化,另一个虚拟机如何得知?
所以静态成员和单例模式都会失效。对于第二点,原因和第一点相同,如果不是位于同一个虚拟机中,线程同步机制就会失去作用。对于第三点,多进程模式下,SharedPreferences的稳定性会下降,我们知道sharedPreferences是基于XML的,它并不能在高并发的情况下保证稳定准确。对于第四点,运行在同一个进程中的组件是属于同一个虚拟机和同一个Application的,所以Application会被多次创建。
现在我们知道,多进程之间的通信会造成一些问题,那么如何避免?
我们先刷个副本,再去打最后这个怪
副本1.Serializable exp+100 hair–
副本2.Parcelable exp+100 hair–
4.Serializable
Android面试中经常会问道Serializable和parcelable的区别,我们先来了解一下Serializable
它是Java提供的一个序列化接口。
何谓序列化?
序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程
何谓反序列化?
指把字节序列恢复为Java对象的过程
你可以这样理解一下序列化,比如说我们要把yUser的信息存储到硬盘,我们新建一个txt保存User中各个属性的值,当我们需要用的时候,再根据txt的值来恢复这个对象。但是有了序列化接口,我们就不必自己去写序列化对象的方法,可以直接用了
Serializable的使用方法很简单,我们只需要让我们的类实现Serializable接口,并在其中声明一个变量如下:
private static final long serialVersionUID=xxxxxxx
这个变量有什么作用呢?总不会是摆设吧?他的作用在于,当我们反序列化的时候需要判断,只有和当前类中的serialVersionUID相等我们才可以反序列化成功。为了防止别人对改序列化的文件做了修改,当我们反序列化的时候,如果不判断serialVersionUID,很有可能造成Crash。
我们写个demo来体会一下
public class User implements Serializable {
public User(int userId,String userName,String passWord){
this.userId=userId;
this.userName=userName;
this.passWord=passWord;
}
public static final long serialVersionUID=1111;
public int userId;
public String userName;
public String passWord;
public static void main(String[] args) throws IOException, ClassNotFoundException {
//序列化
User user = new User(1, "no-hair", "no-money");
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("user.txt"));
out.writeObject(user);
out.close();
//反序列化
ObjectInputStream in = new ObjectInputStream(new FileInputStream("user.txt"));
User rUser = (User) in.readObject();
in.close();
}
}
就是这么简单,我们就能把对象保存到本地,随时可以取出来转换成对象!有两点需要注意,第一静态变量不属于对象属于类,所以不会参与序列化过程,第二用transsient关键字修饰的变量不会参与序列化,大部分情况我们都不用重写里面的方法。
5.Parcelable
Parcelable是另一种序列化方式,和Serializable类似,他也是一个接口,一个类只要实现了这个接口,一个类的对象就可以实现序列化并通过Intent和Binder传递。下面还是通过一个简单的demo来看看parcelable.
public class User implements Parcelable {
public User(int userId,String userName,String passWord){
this.userId=userId;
this.userName=userName;
this.passWord=passWord;
}
public static final long serialVersionUID=1111;
public int userId;
public String userName;
public String passWord;
//反序列化过程
protected User(Parcel in) {
userId = in.readInt();
userName = in.readString();
passWord = in.readString();
}
public static final Creator<User> CREATOR = new Creator<User>() {
@Override
public User createFromParcel(Parcel in) {
return new User(in);
}
@Override
public User[] newArray(int size) {
return new User[size];
}
};
@Override
public int describeContents() {
//内容描述
return 0;
}
//序列化过程
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeInt(userId);
parcel.writeString(userName);
parcel.writeString(passWord);
}
}
这个的使用方式和Serializable差不多简单,不多介绍,下面主要介绍两者的区别和特点。
6.Parcelable和Serializable的区别
既然两者都能够实现序列化和反序列化,那么我们该如何选择,这就要看使用场景了。
Serializable是Java中的序列化接口,使用简单但是开销很大,序列化和反序列化过程中需要大量的IO操作,而Parcelable是Android中序列化方式,他的缺点就是使用起来比较麻烦,但是他的效率高。在使用场景上,如果需要序列化到本地文件,数据库,网络流以方便传输,Android parcelable的设计初衷是由于Serializable的效率过低,为了在程序内不同组件间以及不同Android程序间(AIDL)高效的传输数据而设计,这些数据仅在内存中存在,Parcelable 是通过 IBinder 通信的消息的载体。Parcelable 的性能比 Serializable 好,在内存开销方面较小,所以在内存间数据传输时推荐使用 Parcelable 。Serializable可将数据持久化方便保存,所以在需要保存或网络传输数据时选择 Serializable 。