抖音BoostMultiDex优化实践:Android低版本上APP首次启动时间减少80%

本文介绍了通过BoostMultiDex技术优化Android低版本APP首次启动时间,通过JNI调用避免状态切换问题,利用dvmRawDexFileOpen函数直接在Native状态下进行dexopt,减少异常。将dexopt操作放在单独进程,减少性能影响,并通过非ZIP方式优化DEX,降低整体耗时。优化还包括多级加载策略和进程锁管理,确保最佳加载性能。实测数据显示,BoostMultiDex方案使启动耗时降低80%以上,提高设备活跃数。
摘要由CSDN通过智能技术生成

CHECK_STACK_SUM(mSelf);

dvmChangeStatus(mSelf, THREAD_RUNNING);

}

~ScopedJniThreadState() {

dvmChangeStatus(mSelf, THREAD_NATIVE);

COMPUTE_STACK_SUM(mSelf);

}

在使用dvmCallMethodV调用 Java 方法前,会先切换状态为THREAD_RUNNING,执行完毕后,ScopedJniThreadState析构,再切换回THREAD_NATIVE。这样,JNI 执行DexFile.loadDex就和直接执行 Java 代码一样,状态会有问题。不只是CallStaticXXXMethod,所有使用CallXXXMethod函数在 Native 下调用 Java 方法的情况都是如此。

好在,我们想到了另一个办法:既然 Dalvik 不会对内部类的 JNI 调用做切换,我们就自己写一个 JNI 调用,使其走到 Native 代码中,这样线程就会变为 Native 状态,然后 直接调用虚拟机内部函数 做 dexopt 即可。这样在做 dexopt 的时候,始终会处于 NATIVE 的状态,不会切为 RUNNING,也不会被要求挂起,也就能避免这个问题。

这个虚拟机内部函数就是dvmRawDexFileOpen,我们先来看下它的代码说明:

/*

  • Open a raw “.dex” file, optimize it, and load it.

  • On success, returns 0 and sets “*ppDexFile” to a newly-allocated DexFile.

  • On failure, returns a meaningful error code [currently just -1].

*/

int dvmRawDexFileOpen(const char* fileName, const char* odexOutputName,

RawDexFile** ppDexFile, bool isBootstrap);

这个函数可以用来打开原始 DEX 文件,并且对它做优化和加载。对应到 libdvm.so 中的符号是_Z17dvmRawDexFileOpenPKcS0_PP10RawDexFileb,我们只需要用 dlsym 在 libdvm.so 里面找到它,就可以直接调用了,完整代码如下:

using func = int ()(constchar fileName, constchar* odexOutputName, void* ppRawDexFile, bool isBootstrap);

void* handler = dlopen(“libdvm.so”, RTLD_NOW);

dvmRawDexFileOpen = (func) dlsym(handler, “_Z17dvmRawDexFileOpenPKcS0_PP10RawDexFileb”);

dvmRawDexFileOpen(file_path, opt_file_path, &arg, false);

这样,我们自己写一个 JNI 调用,在 Native 状态下执行上述代码,就能达到完成 ODEX 的目的,从而根本上杜绝这个异常了

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值