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")) { } } |
获取当前进程名的方法如下:
/** * @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; }
二、剥离出一个类,具有同 Application 相同的生命周期方法,每个进程拥有一个该类实例
实现这种方式,一共有涉及到 3 个类,
- 一个是 MaApplication 继承了 Application,是程序的入口,这是一个抽象类,需要子类去实现一些方法
- 一个是 BaseApplicationLogic,这也是基类,由这个类来实现每个进程单独管理 Application 的生命周期,每个进程实现一个该类的子类
- 还有一个类是 PriorityLogicWrapper,它是一个封装类,继承了 Comparable 接口,实现了对 BaseApplicationLogic 按照指定顺序排序(也就是可以按照优先级顺序初始化 BaseApplicationLogic)
首先,我们先把所有 ApplicationLogic 注册到 MaApplication 中;
然后,MaApplication 会根据注册时的进程名信息进行筛选,选择相同进程名的 ApplicationLogic,保存到本进程中;
其次,对这些本进程的 ApplicationLogic 进行实例化;
最后,调用 ApplicationLogic 的 onCreate 方法,实现 ApplicationLogic 与 Application 生命周期同步,同时还有 onTerminate、onLowMemory、onTrimMemory、onConfigurationChanged 等方法,与 onCreate 一致。
流程图如下所示:
代码实现,先看基类 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 { //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); } } } } }
具体大家可以实际操作一下,不是太难
我爱娜娜