问题描述
一般情况下,一个应用程序就一个进程,这个进程的名称就是应用程序包名。Android 的四大组件在 AndroidManifest 文件中注册的时候,有个属性是 android:process,这里可以指定组件的所处的进程。
安卓允许一个App声明多个进程,多个进程初始化时会创建多个Application,可能引发许多不可控问题
问题分析
- 同一个class对象初始化两份,如第三方sdk初始化、数据库资源初始化等
- 同一个广播监听两次,业务混乱导致异常,如设备未关门广播、WIFI广播、退出登录广播等
- 同一个服务绑定两次,可能引发业务混乱,如进程保活循环拉起某些App等
问题解决
方案1:按名称初始化不同的内容
@Override
public void onCreate() {
super.onCreate();
String processName = getProcessName(this, android.os.Process.myPid());
if (processName != null) {
boolean defaultProcess = processName.equals(Constants.REAL_PACKAGE_NAME);
// 默认的主进程启动时初始化应用
if (defaultProcess) {
initAppForMainProcess();
}
// 其他进程启动时初始化对应内容
else if (processName.contains(":webbrowser")) {
} else if (processName.contains(":bgmusic")) {
}
}
/**
* @return null may be returned if the specified process not found
*/
public static String getProcessName(Context cxt, int pid) {
ActivityManager am = (ActivityManager) cxt.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningAppP.rocessInfo> runningApps = am.getRunningAppProcesses();
if (runningApps == null) {
return null;
}
for (RunningAppProcessInfo procInfo : runningApps) {
if (procInfo.pid == pid) {
return procInfo.processName;
}
}
return null;
}
方案2:代理application
在 MaApplication 中直接对 PriorityLogicWrapper 进行操作,无需操作 BaseApplicationLogic 对象
public abstract class MaApplication extends Application {
//mLogicList只持有当前进程的PriorityLogicWrapper对象
private ArrayList<PriorityLogicWrapper> mLogicList;
//mLogicClassMap持有所有进程的PriorityLogicWrapper数组对象
private HashMap<String, ArrayList<PriorityLogicWrapper>> mLogicClassMap;
@Override
public void onCreate() {
super.onCreate();
init();
initializeLogic();
dispatchLogic();
instantiateLogic();
if (null != mLogicList && mLogicList.size() > 0) {
for (PriorityLogicWrapper priorityLogicWrapper : mLogicList) {
if (null != priorityLogicWrapper && null != priorityLogicWrapper.instance) {
//找到当前进程的BaseApplicationLogic实例后,执行其onCreate()方法
priorityLogicWrapper.instance.onCreate();
}
}
}
}
private void init() {
mLogicClassMap = new HashMap<>();
}
public abstract boolean needMultipleProcess();
//由MaApplication的实现类,去实现这个方法,调用registerApplicationLogic()
//注册所有进程的BaseApplicationLogic对象
protected abstract void initializeLogic();
/**
* 添加所有来自不同进程的,不同的BaseApplicationLogic对象到HashMap中
* @param processName 进程名
* @param priority 优先级
* @param logicClass 继承BaseApplicationLogic的对象
* @return
*/
protected boolean registerApplicationLogic(String processName, int priority, @NonNull Class<? extends BaseApplicationLogic> logicClass) {
boolean result = false;
if (null != mLogicClassMap) {
ArrayList<PriorityLogicWrapper> tempList = mLogicClassMap.get(processName);
if (null == tempList) {
tempList = new ArrayList<>();
mLogicClassMap.put(processName, tempList);
}
if (tempList.size() > 0) {
for (PriorityLogicWrapper priorityLogicWrapper : tempList) {
if (logicClass.getName().equals(priorityLogicWrapper.logicClass.getName())) {
throw new RuntimeException(logicClass.getName() + " has registered.");
}
}
}
PriorityLogicWrapper priorityLogicWrapper = new PriorityLogicWrapper(priority, logicClass);
tempList.add(priorityLogicWrapper);
//tempList更新,则mLogicClassMap中的value也跟着更新了,不用再调用mLogicClassMap.put方法
}
return result;
}
/**
* 得到一个属于本进程的ArrayList对象,里面保存着封装类PriorityLogicWrapper
*/
private void dispatchLogic() {
if (null != mLogicClassMap) {
//根据进程名,得到该进程名对应的ArrayList<PriorityLogicWrapper>
mLogicList = mLogicClassMap.get(ProcessUtil.getProcessName(this, ProcessUtil.getMyProcessId()));
}
}
/**
* 取得mLogicList中的PriorityLogicWrapper对象,并按优先级顺序初始化BaseApplicationLogic对象
*/
private void instantiateLogic() {
if (null != mLogicList && mLogicList.size() > 0) {
if (null != mLogicList && mLogicList.size() > 0) {
Collections.sort(mLogicList); //根据进程优先级,按顺序初始化
for (PriorityLogicWrapper priorityLogicWrapper : mLogicList) {
if (null != priorityLogicWrapper) {
try {
/**
* 调用Class.newInstance(),会创建这个Class的实例,但是不会执行Android中这个类相关的生命周期
* **/
priorityLogicWrapper.instance = priorityLogicWrapper.logicClass.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
if (null != priorityLogicWrapper.instance) {
priorityLogicWrapper.instance.setApplication(this);
}
}
}
}
}
}
//Application生命周期的处理,下面方法都类似
@Override
public void onTerminate() {
super.onTerminate();
if (null != mLogicList && mLogicList.size() > 0) {
for (PriorityLogicWrapper priorityLogicWrapper : mLogicList) {
if (null != priorityLogicWrapper && null != priorityLogicWrapper.instance) {
priorityLogicWrapper.instance.onTerminate();
}
}
}
}
@Override
public void onLowMemory() {
super.onLowMemory();
if (null != mLogicList && mLogicList.size() > 0) {
for (PriorityLogicWrapper priorityLogicWrapper : mLogicList) {
if (null != priorityLogicWrapper && null != priorityLogicWrapper.instance) {
priorityLogicWrapper.instance.onLowMemory();
}
}
}
}
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
if (null != mLogicList && mLogicList.size() > 0) {
for (PriorityLogicWrapper priorityLogicWrapper : mLogicList) {
if (null != priorityLogicWrapper && null != priorityLogicWrapper.instance) {
priorityLogicWrapper.instance.onTrimMemory(level);
}
}
}
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (null != mLogicList && mLogicList.size() > 0) {
for (PriorityLogicWrapper priorityLogicWrapper : mLogicList) {
if (null != priorityLogicWrapper && null != priorityLogicWrapper.instance) {
priorityLogicWrapper.instance.onConfigurationChanged(newConfig);
}
}
}
}
}
基类 BaseApplicationLogic,每个进程都要实现一个该类的子类:
public class BaseApplicationLogic {
protected MaApplication mApplication;
public BaseApplicationLogic() {
}
public void setApplication(@NonNull MaApplication application) {
mApplication = application;
}
public void onCreate() {
}
public void onTerminate() {
}
public void onLowMemory() {
}
public void onTrimMemory(int level) {
}
public void onConfigurationChanged(Configuration newConfig) {
}
}
PriorityLogicWrapper,这是一个封装类,实现了 BaseApplicationLogic 的按优先级排列:
public class PriorityLogicWrapper implements Comparable<PriorityLogicWrapper> {
public int priority = 0;
public Class<? extends BaseApplicationLogic> logicClass = null;
public BaseApplicationLogic instance;
public PriorityLogicWrapper(int priority, Class<? extends BaseApplicationLogic> logicClass) {
this.priority = priority;
this.logicClass = logicClass;
}
@Override
public int compareTo(PriorityLogicWrapper o) {
return o.priority - this.priority;
}
}