书到用时方恨少,事非经过不知难。这篇文章主要讲述Android 65K问题之Multidex原理分析及NoClassDefFoundError的解决方法相关的知识,希望能为你提供帮助。
android 65K问题相信困惑了不少人,尽管AS的出来能够通过分dex高速解决65K问题,可是同一时候也easy由于某些代码没有打包到MainDex里引起NoClassDefFoundError。
随着5.0的推出,Android也放出了Multidex
Support Library来解决问题。
Multidex Support
Library能够直接分包处理65K问题。而且不会发生NoClassDefFoundError的情况。
1.使用的话。首先加入依赖库://分包multiDexEnabled必须加入该依赖
compile
‘com.android.support:multidex:1.0.1‘
2.另外开启Multidex开关:buildTypes
{
release
{
minifyEnabled
false
//分包
multiDexEnabled
true
proguardFiles
getDefaultProguardFile(‘proguard-android.txt‘),
‘proguard-rules.pro‘
}
}
3.这时候执行的话可能会报java堆内存错误,因此最好加入上:dexOptions
{
javaMaxHeapSize
"
4g"
incremental
true
}
4.假设你有自己的Application,则改动一下Application使其继承MultiDexApplication:public
class
MyApplication
extends
MultiDexApplication
{
...
}
假设你的Application非常不幸已经继承了其它Application导致无法继承MultiDexApplication的话。那也是能够是,仅仅须要复写该方法并加上该代码:@Override
protected
void
attachBaseContext(Context
base)
{
super.attachBaseContext(base);
MultiDex.install(base);
}
这时候你就能够跑了,详细能够看官方文档,毕竟官方文档里面写得很清楚。
以下我们主要来说下Multidex的实现方法,以下部分来源:http://blog.waynell.com/2015/04/19/android-multidex/
的分析。
Multidex的实现原理
Multidex的实现原理是将class编译进不同的classes.dex文件里。普通情况下。一个APK文件里仅仅包括了一个classes.dex文件。
分包之后就存在一个主的classes.dex,多个副的classes2.dex,classes3.dex…在要启动程序时,Android会先去载入主的classes.dex。然后在程序启动后再去载入其他副的dex。那哪些class应该被编译到主的classes.dex中呢?
先来看下Multidex的编译过程,它由三个不同的gradle task组成:
1 |
collect{variant}MultiDexComponents task |
这个task会读取项目的AndroidManifest.xml文件里注冊的application、Activity、service、receiver、provider、instrumentation相关类,并将其class文件路径写到文件
buidl/intermediates/multi-dex/${variant.dirName}/manifest_keep.txt
中
1 |
shrink{variant}MultiDexComponents task |
这个task会调用ProGuard并依据上一步生成的manifest_keep.txt文件内容去压缩class,剔除没实用到的class。生成一个精简的jar包
buidl/intermediates/multi-dex/${variant.dirName}/componentClasses.jar
1 |
create{variant}MainDexClassList task |
这个task会依据上一步生成的componentClasses.jar去寻找这里面的各个class文字中依赖的class,比方一个class中有一成员变量X。那么X就是依赖的class,componentClasses.jar中全部的class和依赖的class路径都会被写入到文件
buidl/intermediates/multi-dex/${variant.dirName}/maindexlist.txt
中,这个文件里的类都会被编译进主的classes.dex中去。(详情能够查看ClassReferenceListBuilder的实现源代码)NoClassDefFoundErrorMultidex固然是好的,不用再为方法数超过65536而苦恼了。
可是有时往往会带来意想不到的bug。比方NoClassDefFoundError。之前我就在项目中遇到了这个问题。一启动程序就crash了,看log是因为某个类找不到引起的。
【Android 65K问题之Multidex原理分析及NoClassDefFoundError的解决方法】
通过上面的分析,我们已经得知Multidex的原理了,所以要解决一启动程序就NoClassDefFoundError的问题仅仅须要确定该类是否正确被编译到主classes.dex中去了。假设没有被编进去的话,仅仅要改动下maindexlist.txt文件。把这个类加入进去就可以。因为maindexlist.txt这个文件是每次编译时自己主动生成的,手动去改动它是无用的。所以我们能够在gradle编译中新加入一个task,在
create{variant}MainDexClassList
这个task完毕之后再去改动maindexlist.txt文件加入丢失的class。
推荐阅读
- Android 开发笔记___登陆app
- hdoj 4925 Apple tree 最小割
- React Native Android打包apk
- SEO关键字研究工具合集(20大Google关键字规划师替代品)
- 如何修复Android你的连接不是私密的错误(解决方法教程)
- 远程桌面软件(Windows和Mac的10大最佳免费TeamViewer替代品)
- 如何修复Windows 10 NVIDIA GeForce Experience无法打开(解决方法)
- error launching installer,本文教您安装时出现 Error launching installer怎样处理
- 打开光盘镜像文件,本文教您怎样打开光盘镜像文件