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")) {

    }  
}

获取当前进程名的方法如下:

/**
 * @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);
                }
            }
        }
    }

}

具体大家可以实际操作一下,不是太难

我爱娜娜

  • 53
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值