解决Multidex.install产生ANR问题时,遇到startactivity后activity的onCreate方法不执行的问题

zhaoxnshow 发布于 2018/03/06 16:42
阅读 513
收藏 1

最近在做ANR问题调优,发现APP中使用MultiDex进行拆包,导致在低版本机型上出现ANR,于是按照帖子(http://blog.csdn.net/synaric/article/details/53540760)对过程执行优化。但是在低版本(比如4.3)上发现,异步执行MultiDex的LoadResActivity启动之后,其onCreate方法没有被执行,而同样的逻辑在6.0上却可以正常执行,找了好久始终不得其解,还请哪位大神指点迷津,在下感激不尽。

代码片段如下:

public class ApplicationBase extends Application  {

@SuppressWarnings("MismatchedReadAndWriteOfArray")
    private static final byte[] lock = new byte[0];

protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
//        //分包,解决65536问题
//        MultiDex.install(this);
        //Android 5.0以上不需要特别处理
        if (!isAsyncLaunchProcess() && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            if (needWait(base)) {
                /*
                    第一次启动APP由于MultiDex将会非常缓慢,某些低端机可能ANR。
                    因此这里的做法是挂起主进程,开启:async_launch进程执行dexopt。
                    dexopt执行完毕,主进程重新变为前台进程,继续执行初始化。
                    主进程在这过程中变成后台进程,因此阻塞将不会引起ANR。
                 */
                Log.i("ApplicationBase","MultiDex.install() Async");
                DexInstallDeamonThread thread = new DexInstallDeamonThread(this, base);
                thread.start();

                //阻塞等待:async_launch完成加载
                synchronized (lock) {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                thread.exit();
                Log.i("ApplicationBase","ApplicationBase dexopt finished. alloc MultiDex.install()");
            } else {
                Log.i("ApplicationBase","MultiDex.install() directly");
                MultiDex.install(this);
            }
        }
    }

    public boolean isAsyncLaunchProcess() {
        String processName = SystemUtils.getCurrentProcessName(this);
        return processName != null && processName.contains(":async_launch");
    }

    @SuppressWarnings("deprecation")
    private boolean needWait(Context context) {
        //这里实现不唯一,读取一个全局的标记,判断是否初次启动APP
        //这个标记应当随着版本升级而重置
        SharedPreferences sp = SPUtils.getVersionSharedPreferences(context);
        return sp.getBoolean(SPUtils.FIRST_LAUNCH, true);
    }

    private static class DexInstallDeamonThread extends Thread {

        private Handler handler;

        private Context application;

        private Context base;

        private Looper looper;

        public DexInstallDeamonThread(Context application, Context base) {
            this.application = application;
            this.base = base;
        }

        @SuppressLint("HandlerLeak")
        @Override
        public void run() {
            Looper.prepare();
            looper = Looper.myLooper();
            handler = new Handler() {

                @SuppressWarnings("deprecation")
                @Override
                public void handleMessage(Message msg) {
                    synchronized (lock) {
                        lock.notify();
                    }
                    SPUtils
                            .getVersionSharedPreferences(application)
                            .edit()
                            .putBoolean(SPUtils.FIRST_LAUNCH, false)
                            .apply();
                }
            };

            Messenger messenger = new Messenger(handler);
            Intent intent = new Intent(base, LoadResActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.putExtra("MESSENGER", messenger);
            base.startActivity(intent);

            Looper.loop();
        }

        public void exit() {
            if (looper != null) looper.quit();
        }
    }

}

加载中
返回顶部
顶部