Android开发之android中的多进程模式
Android中多进程是指一个应用存在多个进程的情况。
为何使用多进程?
多进程的情况分为两种;
第一种情况是一个应用因为某些原因自身需要采用多进程模式实现,比如有些模块需要在单独的进程的运行,又或者为了加大一个应用可使用的内存通过多进程获取更大的运行内存空间等。Android对单个应用使用的内存进行了限制,不同设备不同大小。
第二种情况:当前应用需要向其他应用获取数据,由于两个应用,需要跨进程的方式来获取数据等。
开启多进程的模式
在AndroidMenifest中指定Android:process属性。
<activity
android:name=".SecondActivity"
android:process=":twoprocess"></activity>
<activity
android:name=".ThirdActivity"
android:process="comzzj.myappartdevelopmentdemo.thirdprocess"></activity>
看一下运行起来进程的名字:
默认进程:
截图02.png
secondActivity的进程:
截图01.pngthirdActivity的进程:
截图03.png从进程的名字可以看出以“:”开头的进程属于应用的私有进程,其他应用的组件不可以和它跑在同一个进程中,而进程名不以“:”开头的进程属于全局进程,其他应用通过shareUID方式可以和它跑在同一个进程中。Android系统会为每个应用分配一个唯一的UID,具有唯一UID的应用才可以共享数据。
多进程模式下的运行机制
下面通过简单的例子看一下通过静态成员变量的值,查看多线程下运行的机制
public class ConstantManager {
public static int CONSTANT_ID = 1;
}
mainActivity的onCreate方法
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ConstantManager.CONSTANT_ID = 2;
Log.d("CONSTANT_ID","MainActivity.CONSTANT_ID:"+ConstantManager.CONSTANT_ID);
}
SecondActivity的onCreate方法
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_second);
Log.d("CONSTANT_ID","SecondActivity.CONSTANT_ID:"+ConstantManager.CONSTANT_ID);
}
截图00.png
从打印日志可以看出,在默认进程中修改的值只会影响当前的进程,对其他进程不会造成任何影响。
Android为每一个应用分配了独立的虚拟机,或者说为每一个进程分配了一个独立的虚拟机,不同虚拟机在内存分配上有不同的地址空间,这就导致在不同虚拟机中访问同一个类对象会产生多份副本。
一般来说,使用多进程会造成如下几个方面的问题:
1、静态成员和单例模式无效
2、线程同步机制完全失效
3、SharedPreferences的可靠性下降
4、Application的多次创建。
前三个问题很容易理解,多进程下去同时操作数据和类,肯定会产生以上问题。
我们主要通过简单测试理解下第四个问题怎么多次创建呢?
获取当前运行进程的名称
public static String getProcessName(Context cxt, int pid) {
ActivityManager am = (ActivityManager) cxt.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningAppProcessInfo> runningApps = am.getRunningAppProcesses();
if (runningApps == null) {
return null;
}
for (RunningAppProcessInfo procInfo : runningApps) {
if (procInfo.pid == pid) {
return procInfo.processName;
}
}
return null;
}
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
Log.d("MyApplication","MyApplication.process:"+getProcessName(getApplicationContext(), Process.myPid()));
}
Paste_Image.png
从log中可以看出,Application执行了三次onCreate,并且每次的进程名称和进程id都不一样。
虽然我们分析了这么多多进程带来的问题,但是不能因为多进程有很多问题就不去正视它,为了解决这个问题,系统为我们提供了很多跨进程通信的方法。虽然不能直接共享内存,但是可以通过跨进程通信(IPC)实现数据交互。