Multidex(二)之 Dex 预加载优化,安卓面试题及答案2020


Multidex(一)之源码解析中分析过MultiDex第一次加载出现ANR的原因是因为**提取Dex以及DexOpt这两个过程都是耗时的操作,而且他们还都发生在主进程。**稍等:主进程,ANR,脑袋里好像闪现一道灵光,**既然在主进程执行会产生ANR,那能不能换个进程执行呢?**橘生淮南则为橘,生于淮北则为枳;换个进程说不定就有突破点。说干就干,凭借程序员机智的大脑,分毫之间,一个优化方案的雏形已经了然于胸:App第一次启动时单独开一个额外优化的进程率先进行Dex提取以及DexOpt的操作,与此同时主进程在后台等待,优化的进程执行完毕之后通知主进程继续往下执行,主进程在执行MultiDex.install时发现已经是提前优化好了Dex,直接执行,非常快,毫秒级别,不会造成卡顿,愉快的往下继续执行。

三、优化方案工作流程图

-----------

四、代码实战


在Application的attachBaseContext中执行优化方案;

@Override

protected void attachBaseContext(Context base) {

super.attachBaseContext(base);

//只有主进程以及SDK版本5.0以下才走。

if (isMainProcess(Application.this) && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {

if (!dexOptDone(base)) {

preLoadDex(base);

}

long startTime = System.currentTimeMillis();

MultiDex.install(this);

LogUtil.i(TAG,“MainProcessCostTime:”+(System.currentTimeMillis() - startTime));

}

}

/**

  • 当前版本是否进行过DexOpt操作。

  • @param context

  • @return

*/

private boolean dexOptDone(Context context) {

SharedPreferences sp = context.getSharedPreferences(

DeviceUtil.getVersionName(context), MODE_MULTI_PROCESS);

return sp.getBoolean(“dexoptdone”, false);

}

/**

  • 在单独进程中提前进行DexOpt的优化操作;主进程进入等待状态。

  • @param base

*/

public void preLoadDex(Context base) {

Intent intent = new Intent(Application.this, PreLoadDexActivity.class);

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

base.startActivity(intent);

while (!dexOptDone(base)) {

try {

//主线程开始等待;直到优化进程完成了DexOpt操作。

Thread.sleep(100);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

然后在PreLoadDexActivity中执行优化的操作,完成后修改标示;

@Override

public void onCreate(Bundle savedInstanceState) {

requestWindowFeature(Window.FEATURE_NO_TITLE);

super.onCreate(savedInstanceState);

overridePendingTransition(0, 0);//取消掉系统默认的动画。

getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

setContentView(R.layout.predexlayout);

new Thread() {

@Override

public void run() {

super.run();

try {

long time = System.currentTimeMillis();

MultiDex.install(getApplication());

LogUtil.i(“lz”, “PreLoadDexActivityCostTime:” + (System.currentTimeMillis() - time));
= System.currentTimeMillis();

MultiDex.install(getApplication());

LogUtil.i(“lz”, “PreLoadDexActivityCostTime:” + (System.currentTimeMillis() - time));

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值