记一次诡异的问题:跟多进程多次执行application的onCreate有关

时间:2022-08-28 20:28:00

原来我们会在application中执行一些初始化的工作,单进程情况下,没什么问题。多进程情况下,如果不区分初始化,那么子进程在创建的时候也会执行application的onCreate方法,如果所有的初始化工作都放在这个方法里面,那么必然会导致这个方法里面的代码被执行两次。

我在初始化代码中,使用了

registerActivityLifecycleCallbacks(new MyActivityLifecycleCallback()); 
来检测activity的生命周期,并且使用了一个类来保存当前可见的一些activity,这些activity在我后面的升级检测中会使用到(即检测到activity在前台的时候不进行静默安装)。

由于我的另外一个进程是个*面的进程,而初始化的时候,也同样执行了registerActivityLifecycleCallbacks方法,里面也使用同一个类(不同的进程空间)来保存了activity的状态,很显然,*面的进程是没有activity的,也就是说后面判断升级安装的时候,由于没有activity,那么就会判断成应用在后台,这样的话,就会直接进行静默安装了。这样就导致了,虽然用户还在前台运行(主进程逻辑,不会进程静默安装),但是后台进程(*面子进程)一定会执行静默安装,一旦执行了静默安装,当前运行的进程(主,子进程)都会被销毁,直接退出到桌面。这样就不符合原来的预期(预期是:用户切换到后台后再执行静默安装)。

所以处理的方式就是在初始化的时候判断进程名,子进程就不要再去进程检测升级的初始化工作了。

检测多进程区分onCreate的方法:

Android的Application中onCreate执行多次解决方案

@Override
public void onCreate() {
super.onCreate();
String processName = getProcessName(this);
if (processName!= null) {
if(processName.equals("com.soubw.prodemo")){
//初始化com.soubw.prodemo以包名为进程名,项目默认的进程
} else if(processName.equals("com.soubw.prodemo:login")){
//初始化com.soubw.prodemo:login
}else if(processName.equals("com.wxj.register")){
//初始化com.wxj.register
}else{

}
}
}


private String getProcessName(Context context) {
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> runningApps = am.getRunningAppProcesses();
if (runningApps == null) {
return null;
}
for (ActivityManager.RunningAppProcessInfo proInfo : runningApps) {
if (proInfo.pid == android.os.Process.myPid()) {
if (proInfo.processName != null) {
return proInfo.processName;
}
}
}
return null;
}