解决了艺龙闪退的问题后,认为解决交通银行闪退会是同类问题,可是我失望了,没有任何日志输出。
只能反编译看了,发现smali文件夹很小,全部的文件只有如下。
/home/lgy/decode/com.bankcomm.Bankcomm_3110/smali/com/secneo/apkwrapper/ApplicationWrapper.smali
/home/lgy/decode/com.bankcomm.Bankcomm_3110/smali/com/secneo/apkwrapper/BuildConfig.smali
/home/lgy/decode/com.bankcomm.Bankcomm_3110/smali/com/secneo/apkwrapper/DexInstall.smali
/home/lgy/decode/com.bankcomm.Bankcomm_3110/smali/com/secneo/apkwrapper/DexInstall$V4.smali
/home/lgy/decode/com.bankcomm.Bankcomm_3110/smali/com/secneo/apkwrapper/DexInstall$V14.smali
/home/lgy/decode/com.bankcomm.Bankcomm_3110/smali/com/secneo/apkwrapper/DexInstall$V19.smali
/home/lgy/decode/com.bankcomm.Bankcomm_3110/smali/com/secneo/apkwrapper/FilesFileObserver.smali
/home/lgy/decode/com.bankcomm.Bankcomm_3110/smali/com/secneo/apkwrapper/Helper.smali
/home/lgy/decode/com.bankcomm.Bankcomm_3110/smali/com/secneo/apkwrapper/R.smali
/home/lgy/decode/com.bankcomm.Bankcomm_3110/smali/com/secneo/apkwrapper/R$attr.smali
/home/lgy/decode/com.bankcomm.Bankcomm_3110/smali/com/secneo/apkwrapper/R$dimen.smali
/home/lgy/decode/com.bankcomm.Bankcomm_3110/smali/com/secneo/apkwrapper/R$drawable.smali
/home/lgy/decode/com.bankcomm.Bankcomm_3110/smali/com/secneo/apkwrapper/R$id.smali
/home/lgy/decode/com.bankcomm.Bankcomm_3110/smali/com/secneo/apkwrapper/R$layout.smali
/home/lgy/decode/com.bankcomm.Bankcomm_3110/smali/com/secneo/apkwrapper/R$menu.smali
/home/lgy/decode/com.bankcomm.Bankcomm_3110/smali/com/secneo/apkwrapper/R$string.smali
/home/lgy/decode/com.bankcomm.Bankcomm_3110/smali/com/secneo/apkwrapper/R$style.smali
同时lib文件夹下有libDexHelper.so,搜了下这个是使用了梆梆加密,启动进程后动态加载dex然后使用ClassLoader加载真正的application类启动自己的代码。
看了下DexInstall其实就是和目前源码中的MultiDex,它俩除了名字外代码完全一样。
frameworks/multidex/library/src/android/support/multidex/MultiDex.java
MultiDex最初是FaceBook为了突破dalvik虚拟机方法数65535创建的一套机制,后来腾讯的团队引进并修改,进而国内各个app团队都在使用了。其实65535的限制在art虚拟机上已经不复存在了,但是还是继续使用这套机制的原因一个是为了兼容旧机器,另外一个就是实现Android代码的动态更新。在交通银行这个app上的作用最主要是加密,app代码一开始就直接跑到native代码中,然后dex的位置,咋加载通过简单的反编译是无法确定的。其实从文件夹大小可以看出代码都应该在assets目录中,去看的话是一片混乱,根本无法确认dex的位置。
MultiDex的日志中的注释中也提及了最多支持v20的版本,查看代码:
private static final class V19 {
private static void install(ClassLoader loader, List<File> additionalClassPathEntries,
File optimizedDirectory)
throws IllegalArgumentException, IllegalAccessException,
NoSuchFieldException, InvocationTargetException, NoSuchMethodException {
/* The patched class loader is expected to be a descendant of
* dalvik.system.BaseDexClassLoader. We modify its
* dalvik.system.DexPathList pathList field to append additional DEX
* file entries.
*/
Field pathListField = findField(loader, "pathList");
...
}
}
首先使用反射获取pathList,查看
libcore/dalvik/src/main/java/dalvik/system/PathClassLoader.java
其中根本无此变量,而此变量在父类BaseDexClassLoader
libcore/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java
private final DexPathList pathList;
可以看出DexInstall中的代码和目前的ClassLoader是对不上的,本以为这个是个突破口,但是修改ClassLoader相关代码后没啥效果。
其实最终发现这个问题很简单,应为DexInstall的代码就是起迷惑作用的,app根本没有使用DexInstall的代码,它调用so库后加载代码的流程完全不为所知。闪退的原因是个盲点,和手机版本有关,同事们和我用的都是eng版本的rom,使用user版本rom后无此问题。闪退是app检测到eng版本后主动退出的,和系统代码无任何关系。