下面的内容主要讲的是
- IPC 的简介
- 去开启多进程模式
- 分析里面会遇到的一些问题
1. Android 中 IPC 简介
1.1 IPC含义
IPC就是 Inter-Process Communication 的缩写,含义为进程间通信或者跨进程通信,是指两个进程之间进行数据交换的过程。
1.2 进程与线程
线程:是 CPU 调度的最小单元,同时线程是一种有限的系统资源。
进程:一般指一个执行单元,在 PC 和移动设备上指的是一个程序或者一个应用。
两者之间的关系:一个进程可以包含多个线程,一次进程和线程是包含和被包含的关系。最简单情况下,一个进程可以只有一个线程,即主线程,在 Android 中主线程也叫做 UI 线程。
2. Android 中开启多进程模式以及遇到的问题
2.1开启多进程模式
Android 中多进程模式是指一个应用中存在多个进程的情况,因此这里不讨论两个应用之间的多进程情况。在 Android 中使用多进程只有一种方法,那就是给四大组件(Activity、Service、Receiver、ContentProvider)在 AndroidMenifest 中指定 android:process 属性。下面是一个在 Android 中创建多进程的示例:
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".TwoActivity"
android:process=":remote"/>
<activity android:name=".ThreeActivity"
android:process="com.example.user.myipc.remote"/>
上面示例分别为 TwoActivity 和ThreeActivity 指定了 process 属性,并且属性值不同,这就意味着当前应用又增加了两个新进程。上面两个 Activity 分别指定的是":remote" 和 "com.example.user.myipc.remote" ,这两个有什么不同呢?
":" 是一种简单的写法,含义是在当前的进程名前面附加上当前的包名,它的完整写法就是 ThreeActivity 的 process 属性。
到此为止,你已经学会了如何开启多进程模式。
2.2 多进程模式的运行机制
上面讲解了如何开启多进程模式,下面来看开启多进程模式后的小问题;我们新建一个类,名字为 UerManager,这个类里面的内容为一个公共的静态变量:
/**
* Name:Wu.
* Date:2018/10/28.
* Describe:静态成员变量
*/
public class UserManager {
public static String userId = "1";
}
我们在 MainActivity 中将这个变量重新赋值为 “2” ,打印并启动TwoActivity,MainActivity 中代码为:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
UserManager.userId = "2";
Log.e("=MainActivity", UserManager.userId);
//启动TwoActivity
Intent intent = new Intent(this,TwoActivity.class);
startActivity(intent);
}
接着在 TwoActivity 中打印出来这个变量,TwoActivity 中代码为:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.e("=TwoActivity", UserManager.userId);
}
下面是打印结果:
可以看出,我们已经将静态变量的值改变了,但它在 TwoActivity 中打印结果仍然是 "1",这就是多进程所带来的问题。并不是指定完 android:process 属性那么简单。
Android 会为每一个应用分配一个独立的虚拟机,在我们上面的例子中也是这样,分配了两个虚拟机,它们都存在 UserManager 类并且两个类是互不干扰的;所以出现了上面的情况。一般来说,使用多进程会造成如下几方面的问题:
- 静态变量和单例模式失效
- 线程同步机制失效
- SharedPreferences 的可靠性下降
- Application 会多次创建
第一个问题已经分析过了,第二个和第一个问题是类似的。第三个问题是因为 SharedPreferences 不支持两个进程同时执行写操作,否则会导致有一定概率的数据丢失,这是因为 SharePreferences 底层是通过读写 XML 文件来实现的,并发写是可能出现问题的。最后一个问题,也是显然的,每启动一个进程就相当于分配了一个独立的虚拟机,因此会把应用重新启动一遍。所以不同的进程会拥有独立的虚拟机、Application 以及内存空间。
由此看来,开启多进程虽然简单,但是实现多进程通信去传递数据却不怎么容易。