在Android中使用多进程的一般方式为在mainfest文件中对组件进行process设置,从而创建使用多进程,一般使用多进程的目的是为了隔离和内存分担。
设置多进程的方式也包括两种:
一种是私有进程,android:process=":remote",以冒号开头,则实际的进程名为 程序包名+私有进程名。这种设置形式表示该进程为当前应用的私有进程,其他应用的组件不可以和它跑在同一个进程中。
一种是进程名称不以“:”开头的进程都可以叫全局进程,如android:process=“com.remote”,以小写字母开头,表示运行在一个以这个名字命名的全局进程中,其他应用通过设置相同的ShareUID可以和它跑在同一个进程。
Q1、我们常说的父进程子进程,那么我们在应用中通过在mainfest中process设置的子进程,它的父进程是谁?
在对进程的认识过程中大家都知道应用有主进程和子进程之分,而我们同时也知道启动应用时,应用进程是从 zygote进程fork出来的,而获取应用的父进程,可以通过android.os.process.myPpid()方法获取,此方法需要通过反射来调用
Class<Process> processClass = android.os.Process.class;
Process process = null;
try {
process = processClass.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
int ppid = 0;
try {
Method method = processClass.getMethod("myPpid");
ppid = (int) method.invoke(process);
} catch (Exception e) {
e.printStackTrace();
}
结合adb shell ps命令可以确认,所有应用的父进程都是zygote进程。
Q2、为什么ps命令下android进程id是从1开始的?那进程id为0的是什么进程?
其实pid=0的进程是idle进程,其前身是系统创建的第一个进程,也是唯一一个没有通过fork或者kernel_thread产生的进程。完成加载系统后,演变为进程调度、交换。
Q3、假设这样一个场景,两个应用对同一个lib进行依赖,同时lib中的service组件设置为android:process=“com.remote”,两个应用再设置同样的android:sharedUserId=“my.center”,那会产生什么效果?service是有一个还是多个实例?如果是多个service实例,那如果通过aidl形式去绑定service,又是绑定的哪一个呢?
首先通过代码验证,可以发现两个应用启动各自lib下面的子进程service,实际只产生了一个进程, 但是子进程的application执行了两次,分别对应两个应用设置的application,service也产生了两个实例,且设置的静态变量也无法共享,即虽然是同一进程,但是内存未得到共享,而从系统任务栈里移除任何一个应用,此进程都会跟随死亡,如果通过aidl形式去绑定service,被绑定的service由intent的package决定。
此处留有一个疑问,上述情况下,同一进程应该如何互访对象?