本编文章是在阅读:Android 架构思考 (模块化、多进程) 过程中,结合自己的理解,对 Android 开启多进程,会导致 Application 重复创建问题进行一个总结。
Android 开启多进程 一般情况下,一个应用程序就一个进程,这个进程的名称就是应用程序包名。Android 的四大组件在 AndroidManifest 文件中注册的时候,有个属性是 android:process,这里可以指定组件的所处的进程。
一个进程情况下,Application 的 onCreate 方法只会执行一次,但如果应用中采用多进程方式,onCreate 方法会执行多次。
解决 Application 的 onCreate 方法多次调用 总结了两种实现方式:
一、根据不同的进程名字进行不同数据的初始化。 这是现在网络上通用的方法,在自定义的 Application 的 onCreate 方法中控制不同进程的初始化
代码如下:
@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" )) { } }
获取当前进程名的方法如下:
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 ; }
二、剥离出一个类,具有同 Application 相同的生命周期方法,每个进程拥有一个该类实例 这就是文章开头提到的博客中使用的方式 Android 架构思考 (模块化、多进程)
实现这种方式,一共有涉及到 3 个类,
一个是 MaApplication 继承了 Application,是程序的入口,这是一个抽象类,需要子类去实现一些方法
一个是 BaseApplicationLogic,这也是基类,由这个类来实现每个进程单独管理 Application 的生命周期,每个进程实现一个该类的子类
还有一个类是 PriorityLogicWrapper,它是一个封装类,继承了 Comparable 接口,实现了对 BaseApplicationLogic 按照指定顺序排序(也就是可以按照优先级顺序初始化 BaseApplicationLogic)
首先,我们先把所有 ApplicationLogic 注册到 MaApplication 中; 然后,MaApplication 会根据注册时的进程名信息进行筛选,选择相同进程名的 ApplicationLogic,保存到本进程中; 其次,对这些本进程的 ApplicationLogic 进行实例化; 最后,调用 ApplicationLogic 的 onCreate 方法,实现 ApplicationLogic 与 Application 生命周期同步,同时还有 onTerminate、onLowMemory、onTrimMemory、onConfigurationChanged 等方法,与 onCreate 一致。
流程图如下所示:多进程Application启动流程
代码实现,先看基类 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; } }
在 MaApplication 中直接对 PriorityLogicWrapper 进行操作,无需操作 BaseApplicationLogic 对象
public abstract class MaApplication extends Application { private ArrayList<PriorityLogicWrapper> mLogicList; 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) { priorityLogicWrapper.instance.onCreate(); } } } } private void init () { mLogicClassMap = new HashMap<>(); } public abstract boolean needMultipleProcess () ; protected abstract void initializeLogic () ; 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); } return result; } private void dispatchLogic () { if (null != mLogicClassMap) { mLogicList = mLogicClassMap.get(ProcessUtil.getProcessName(this , ProcessUtil.getMyProcessId())); } } 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 { priorityLogicWrapper.instance = priorityLogicWrapper.logicClass.newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } if (null != priorityLogicWrapper.instance) { priorityLogicWrapper.instance.setApplication(this ); } } } } } } @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); } } } } }
本文链接:http://agehua.github.io/2017/02/21/Multi-Process-Dispatch/
------------------------------------------------------------------------------------------------------------------------------
Enjoy it ? Donate me ! 欣赏此文?求鼓励,求支持!
------------------------------------------------------------------------------------------------------------------------------
Enjoy it ? Donate me ! 欣赏此文?求鼓励,求支持!