No original dex files found for dex location /system/app/apk_map/apk_map.apk

类似问题博客:Android内置系统apk问题_local_dex_preopt := nostripping-CSDN博客

问题背景

项目中期需要出一个user版本测试ROM性能指标。于是和SCM沟通,从服务器出了一个user版本。拿到版本后烧录上设备查看情况,结果进入桌面后一段时间,设备反复重启。于是开始了和该问题的搏斗过程。

问题分析过程

异常日志的抓取

user版本adb默认关闭,开机后设备又反复重启,没有机会手动打开。如何抓取日志成为了一个问题。尝试修改代码打开user版本adb权限,并本地编译ROM版本来调试。打开user版本adb的方法参考:https://blog.csdn.net/wxd_csdn_2016/article/details/118152876

异常日志分析

从日志中可以发现很多次com.gwm.app.map这个进程崩溃了。在Android中,常驻进程反复重启多次后,确实会触发Android系统重启,这个和现象一致,初步定位是这个异常导致的。于是开始详细分析这个异常。看下堆栈:

01-01 00:00:29.301  2386  2386 E AndroidRuntime: FATAL EXCEPTION: main
01-01 00:00:29.301  2386  2386 E AndroidRuntime: Process: com.gwm.app.map, PID: 2386
01-01 00:00:29.301  2386  2386 E AndroidRuntime: java.lang.RuntimeException: Unable to instantiate application com.gwm.map.view.App: java.lang.ClassNotFoundException: Didn't find class "com.gwm.map.view.App" on path: DexPathList[[zip file "/system/app/apk_map/apk_map.apk"],nativeLibraryDirectories=[/system/app/apk_map/lib/arm, /system/app/apk_map/apk_map.apk!/lib/armeabi-v7a, /system/lib, /system/product/lib, /system/lib, /system/product/lib]]
01-01 00:00:29.301  2386  2386 E AndroidRuntime:    at android.app.LoadedApk.makeApplication(LoadedApk.java:1069)
01-01 00:00:29.301  2386  2386 E AndroidRuntime:    at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5981)
01-01 00:00:29.301  2386  2386 E AndroidRuntime:    at android.app.ActivityThread.access$1100(ActivityThread.java:204)
01-01 00:00:29.301  2386  2386 E AndroidRuntime:    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1672)
01-01 00:00:29.301  2386  2386 E AndroidRuntime:    at android.os.Handler.dispatchMessage(Handler.java:106)
01-01 00:00:29.301  2386  2386 E AndroidRuntime:    at android.os.Looper.loop(Looper.java:193)
01-01 00:00:29.301  2386  2386 E AndroidRuntime:    at android.app.ActivityThread.main(ActivityThread.java:6808)
01-01 00:00:29.301  2386  2386 E AndroidRuntime:    at java.lang.reflect.Method.invoke(Native Method)
01-01 00:00:29.301  2386  2386 E AndroidRuntime:    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
01-01 00:00:29.301  2386  2386 E AndroidRuntime:    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
01-01 00:00:29.301  2386  2386 E AndroidRuntime: Caused by: java.lang.ClassNotFoundException: Didn't find class "com.gwm.map.view.App" on path: DexPathList[[zip file "/system/app/apk_map/apk_map.apk"],nativeLibraryDirectories=[/system/app/apk_map/lib/arm, /system/app/apk_map/apk_map.apk!/lib/armeabi-v7a, /system/lib, /system/product/lib, /system/lib, /system/product/lib]]
01-01 00:00:29.301  2386  2386 E AndroidRuntime:    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:134)
01-01 00:00:29.301  2386  2386 E AndroidRuntime:    at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
01-01 00:00:29.301  2386  2386 E AndroidRuntime:    at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
01-01 00:00:29.301  2386  2386 E AndroidRuntime:    at android.app.AppComponentFactory.instantiateApplication(AppComponentFactory.java:50)
01-01 00:00:29.301  2386  2386 E AndroidRuntime:    at android.app.Instrumentation.newApplication(Instrumentation.java:1120)
01-01 00:00:29.301  2386  2386 E AndroidRuntime:    at android.app.LoadedApk.makeApplication(LoadedApk.java:1061)
01-01 00:00:29.301  2386  2386 E AndroidRuntime:    ... 9 more
01-01 00:00:29.301  2386  2386 E AndroidRuntime:    Suppressed: java.io.IOException: No original dex files found for dex location /system/app/apk_map/apk_map.apk
01-01 00:00:29.301  2386  2386 E AndroidRuntime:        at dalvik.system.DexFile.openDexFileNative(Native Method)
01-01 00:00:29.301  2386  2386 E AndroidRuntime:        at dalvik.system.DexFile.openDexFile(DexFile.java:354)
01-01 00:00:29.301  2386  2386 E AndroidRuntime:        at dalvik.system.DexFile.<init>(DexFile.java:101)
01-01 00:00:29.301  2386  2386 E AndroidRuntime:        at dalvik.system.DexFile.<init>(DexFile.java:75)
01-01 00:00:29.301  2386  2386 E AndroidRuntime:        at dalvik.system.DexPathList.loadDexFile(DexPathList.java:394)
01-01 00:00:29.301  2386  2386 E AndroidRuntime:        at dalvik.system.DexPathList.makeDexElements(DexPathList.java:354)
01-01 00:00:29.301  2386  2386 E AndroidRuntime:        at dalvik.system.DexPathList.<init>(DexPathList.java:164)
01-01 00:00:29.301  2386  2386 E AndroidRuntime:        at dalvik.system.BaseDexClassLoader.<init>(BaseDexClassLoader.java:74)
01-01 00:00:29.301  2386  2386 E AndroidRuntime:        at dalvik.system.BaseDexClassLoader.<init>(BaseDexClassLoader.java:65)
01-01 00:00:29.301  2386  2386 E AndroidRuntime:        at dalvik.system.PathClassLoader.<init>(PathClassLoader.java:64)
01-01 00:00:29.301  2386  2386 E AndroidRuntime:        at com.android.internal.os.ClassLoaderFactory.createClassLoader(ClassLoaderFactory.java:73)
01-01 00:00:29.301  2386  2386 E AndroidRuntime:        at com.android.internal.os.ClassLoaderFactory.createClassLoader(ClassLoaderFactory.java:88)
01-01 00:00:29.301  2386  2386 E AndroidRuntime:        at android.app.ApplicationLoaders.getClassLoader(ApplicationLoaders.java:74)
01-01 00:00:29.301  2386  2386 E AndroidRuntime:        at android.app.ApplicationLoaders.getClassLoader(ApplicationLoaders.java:40)
01-01 00:00:29.301  2386  2386 E AndroidRuntime:        at android.app.LoadedApk.createOrUpdateClassLoaderLocked(LoadedApk.java:727)
01-01 00:00:29.301  2386  2386 E AndroidRuntime:        at android.app.LoadedApk.getClassLoader(LoadedApk.java:810)
01-01 00:00:29.301  2386  2386 E AndroidRuntime:        at android.app.LoadedApk.getResources(LoadedApk.java:1032)
01-01 00:00:29.301  2386  2386 E AndroidRuntime:        at android.app.ContextImpl.createAppContext(ContextImpl.java:2357)
01-01 00:00:29.301  2386  2386 E AndroidRuntime:        at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5888)
01-01 00:00:29.301  2386  2386 E AndroidRuntime:        ... 8 more

初步认为是加载类时,找不到类导致的,找不到类的原因是找不到对应的dex文件。

dex文件去哪里了?

从本地编译out目录中,取出对应的apk文件,解压缩发现,确实没有classes.dex这样的文件。


找到apk的服务器版本,同样解压缩发现有classes.dex文件。


现在有两个问题:
1.classes.dex文件是什么时候丢失的?
2.userdebug版本为什么没有这个问题?
本地再次编译userdebug版本,同样查看解压后的apk情况,classes.dex文件在userdebug版本中是存在的。而user版本在编译时,就将apk中的classes.dex文件做了剔除。并同时生成了编译优化后的oat文件夹,里面包含了odex和vdex文件(android 9)。目前可以知道,user和userdebug在编译时做的dex优化策略不一样。关于dex优化的配置策略可以参考:https://source.android.com/devices/tech/dalvik/configure

为什么user版本的dex优化导致应用类加载异常

dex优化是android原生提供的一种预编译优化策略。按理说不会导致应用启动异常。继续分析日志,发现查找dex文件的路径是/system/app/apk_map/apk_map.apk,user版本中apk文件中的classes.dex文件已经被剔除了,此刻找不到也是合理的,但是为什么不从oat文件中加载呢?在/data/dalvik-cache/arm下也可以看到文件system@app@apk_map@apk_map.apk@classes.dex和system@app@apk_map@apk_map.apk@classes.vdex。此时怀疑应用自己实现了一个dex的加载机制,导致即使做了dex优化,但是依然从apk文件中加载classes.dex文件。因为user版本的日志太少,没有更多的线索可以分析了,于是切换到userdebug版本,并在dex文件加载流程中,新增了一些关键日志,跟踪下业务流程。userdebug中的关键日志:

01-01 00:00:47.824  3157  3157 I ARouter::: VM with name 'Android' has multidex support

可以知道,这个应用使用了ARouter这个库,从网络了解,这个库提供了组件间的调用解耦功能。通过开放的源码也可以知道,有自己实现一套class文件的查找以及dex文件的加载业务逻辑。这样整个问题的根因就理清楚了。

总结

导致该问题的原因是user版本在编译集成apk时,做了dex优化,并剔除了apk文件中的classes.dex文件。ARouter在加载class时,依然还是从apk中的classes.dex去查找。因为文件被剔除了,查找失败,导致class最终加载失败,应用进程异常退出。

解决方案

1.修改ARouter类加载路径查找机制,适配dex文件被剔除的情况。
2.在编译集成apk时,给这个apk增加LOCAL_DEX_PREOPT := nostripping配置,这样不会剔除apk文件中的classes.dex文件。可以保证ARouter找到class。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值