AndFix(续) - MultiDex
来源:互联网 发布:数据库应用有什么用 编辑:程序博客网 时间:2024/05/17 06:58
前言:
刚跌进了几个坑,又呛过了几条河,怎么程序bug它就这么多….
问题描述:
之前集成了AndFix,一路毫无障碍的过去了,可以看我的Android 热修复 - AndFix 使用心得,这是基本使用。然后搭档在MainActivity里面加了几个新类,我打完补丁,看到了一些奇怪的log,不过补丁确实是打出来了,正确的log是如前面介绍AndFix使用的文章中的log,就只会告诉你 add Modified method:……,其它什么都不会有,,结果在测试的时候,bugApk在loadPatch之后,再次打开APP,报错了,恩,没错 ClassNotFoundException & IllegaleAccessException,大写的蒙蔽!!!
沉思了一会儿,我把问题定位在 MultiDexApplication ,不知道这个的童鞋Google一下就出来,简而言之这个类的添加就是为了解决android 中 dex文件方法超出65536限制的情况。
分析:
既然之前的demo成功了,那么问题就不该是在AndFix上面,就只有可能是AndFix的patch机制和我的代码冲突了,于是我找到了关于AndFix的具体运作原理的博文:Android热补丁之AndFix原理解析。仔细阅读这篇博文后,对于我的问题简单的描述下:
1.使用 MultiDexApplication 之后,超出主dex限制的类会被打包成另外一个辅dex,而且除了一些比较重要的类也就是和APP启动有关的类会被优先打到主dex中,一些不影响APP启动的类的优先级次之,而且不是固定的。
2.AndFix制作patch补丁包的时候,仅仅比较了主dex文件,没有去比较其它的dex文件
那么问题就很明显了,我的问题就出在,我的bug.apk和fix.apk,dex都是不一定的,或者说我要修复的类都不一定在要比对的相应的dex包中,那么一定就会出问题。
思路一:
修改AndFix的patch机制,以及修改加载补丁的机制。这一定是可以实现的,而且我顺着这个思路也确实从网上找到了相应的牛人写的分享博文:AndFix支持Multidex的解决方案。他的思路非常明确,就是通过改变patch的比较机制,然后代码注入,最后修改相应的补丁机制。虽然思路我看明白了,而且这也是一劳永逸的方法,但是是需要大量的时间成本和测试的,项目一直赶着上线,我只能默默放弃(PS:而且感觉真的好复杂啊)。
思路二:
思路一至少目前不能投入那么大的精力去使用,那么针对项目如此着急的情况下,只能想想别的:
1.因为程序方法太多导致必须使用 MultiDexApplication ,要么就使用 dex 分包的技术,事实上都是一样的。
2.类找不是因为我打包的时候主dex中的类,或者说我需要的类没有被指定的打包到主dex中,导致了ClassNotFoundException。
那么,很显然,要解决的问题就是我需要指定我需要的类必须被打包到主dex文件中,简而言之:我要控制 dex 打包的部分流程,也就是控制那些类必须在主dex中。
解决:
参考博客:Android 分Dex (MultiDex)
思路:在build.gradle中配置和打包相关的配置文件,dex 文本,其中放入的类就会被打包到classes.dex中。
上具体图和代码:
build.gradle:
android { compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } compileSdkVersion 23 buildToolsVersion "24" defaultConfig { applicationId "com.xxx.xxx" minSdkVersion 14 targetSdkVersion 23 versionCode 14 versionName "2.1.5" multiDexEnabled = true ndk { abiFilter "armeabi" } } lintOptions { abortOnError false } productFlavors { ... } packagingOptions { exclude 'META-INF/DEPENDENCIES' exclude 'META-INF/NOTICE' exclude 'META-INF/LICENSE' exclude 'META-INF/LICENSE.txt' exclude 'META-INF/NOTICE.txt' exclude 'META-INF/ASL2.0' exclude 'META-INF/notice.txt' } dexOptions { javaMaxHeapSize "2g" } useLibrary 'org.apache.http.legacy' sourceSets.main { assets.srcDirs = ['src/main/assets', 'src/assets/'] jni.srcDirs = [] } afterEvaluate { tasks.matching { it.name.startsWith('dex') }.each { dx -> if (dx.additionalParameters == null) { dx.additionalParameters = [] } dx.additionalParameters += '--multi-dex' dx.additionalParameters += "--main-dex-list=$projectDir/dex".toString() } }}
要贴加的就是
afterEvaluate { tasks.matching { it.name.startsWith('dex') }.each { dx -> if (dx.additionalParameters == null) { dx.additionalParameters = [] } dx.additionalParameters += '--multi-dex' dx.additionalParameters += "--main-dex-list=$projectDir/dex".toString() } }
配置贴的比较全,相信看一下都会懂了。
再贴下 dex 的 txt 文本的位置:
dex和build.gradle同级。
dex 文件的具体内容:
android/support/multidex/CoreApiHelper/classandroid/support/multidex/UpdateAppEntity/classandroid/support/multidex/ISuccessBaseData/classandroid/support/multidex/HawkUtils/classandroid/support/multidex/NaviBottomBar/class...
亲测是可以用,感谢以上两篇博主的帮助,还有一些没有列出来的博文。
至此,AndFix线下就已经OK了,不会有乱七八糟的问题,当然我这个方法其实也是有隐患的,如果你是插件化的APP,那么我这个方法直接忽略,看思路一中介绍的方法,另外,事实上我这个方法也只是指标不治本,这是无奈之举,项目集成了太多类库,而且有点积重难反,刚刚接手的时候已经花了很大的力气删掉一些无用的类和方法、类库,期待公司给出时间重构吧。
如果,有朋友使用了思路一中的方法,希望能写一篇博客分享出来,毕竟那才是一劳永逸的正确方法。
- AndFix(续) - MultiDex
- andfix
- AndFix
- MultiDex
- MultiDex
- MultiDex
- multidex
- multidex
- AndFix修复
- Andfix使用说明
- Andfix QA
- Andfix使用说明
- AndFix使用说明
- AndFix Mac
- MultiDex源码
- MultiDex使用方法
- android MultiDex
- 遭遇MultiDex
- 集训 Poj 3669 BFS
- LintCode(easy)111.爬楼梯(bug集)
- Linux IO实时监控iostat命令详解
- 走遍亚洲 —— 东南亚
- 迅游网游加速器2016 绿色版
- AndFix(续) - MultiDex
- 只读事务(@Transactional(readOnly = true))的一些概念
- 项目实战--svn讲解
- mysql列与注释修改SQL语句
- BIO | NIO | AIO释疑
- atoi函数实现
- android中的图像压缩
- ibatis一次sql过程
- (POJ1149)PIGS(建图+EK模板,Ford-fulkerson)