关闭

Building Apps with Over 65K Methods

标签: android studioandroid
44人阅读 评论(0) 收藏 举报

一、起源

在Android项目中,添加了某一个第三方类库后,构建报错,提示java.lang.VerifyError

二、解决

于是google了一下,Android Doc文档给出的解释是,尝试去加载一个在验证阶段未通过的类,又看了stackoverflow上一些问题的解释,确定是APP Methods 个数超过65536导致的问题,要解决这个问题,需要使用multiDex,通过以下两步完成配置。

1.配置 multiDex构建选项

在gradle中添加multiDex构建的方法:

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.0"

    defaultConfig {
        ...
        minSdkVersion 14
        targetSdkVersion 21
        ...

        // Enabling multidex support.
        multiDexEnabled true
    }
    ...
}

dependencies {
  compile 'com.android.support:multidex:1.0.0'
}

2.在APP的Application配置MultiDex

1>如果未自定义Application

<application
    ...
    android:name="android.support.multidex.MultiDexApplication">
    ...
</application>
2>如果自定义了Application,那么需要在Application的attachBaseContext方法中配置multiDex

@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(base);

    MultiDex.install(this);
}

Tips:可能遇到的问题,如果只是在gradle中添加MultiDex选项,没有在Application中配置,当在项目中添加新的类时,编译不会报错,运行时,报Runntime Error Java.lang.ClassNotDefError.

三、延展

1.超长的编译时间

添加multiDex之后,编译时间超长,严重的影响了开发效率

在Android的官方网站查了下MultiDex相关的资料,找到了一些优化解决方案

1>原因:

当添加multiDex配置后,每次构建APP时,会把类分开到不同的dex文件,一个Primary Dex(classes.dex) 和多个Support Dex 文件(classes2.dex, classes3.dex),构建系统需要经过复杂的策略决定哪些类放到 Primary Dex文件,哪些类放到Support Dex中

2>优化方案

可以通过Android 的 productFlavors来优化这个问题

android {
    productFlavors {
        // Define separate dev and prod product flavors.
        dev {
            // dev utilizes minSDKVersion = 21 to allow the Android gradle plugin
            // to pre-dex each module and produce an APK that can be tested on
            // Android Lollipop without time consuming dex merging processes.
            minSdkVersion 21
        }
        prod {
            // The actual minSdkVersion for the application.
            minSdkVersion 14
        }
    }
          ...
    buildTypes {
        release {
            runProguard true
            proguardFiles getDefaultProguardFile('proguard-android.txt'),
                                                 'proguard-rules.pro'
        }
    }
}
dependencies {
  compile 'com.android.support:multidex:1.0.0'
}
在productFlavors中添加了两个变量,一个development,一个product,同步gradle之后,会生成四个构建变量 devDebug devRelease, prodDebug, prodRelease,在studio的Build Variants中配置在开发时,使用devDebug,发布时,使用prodRelease,

这样在开发的时候,设置的最低编译版本是21,发布时,使用的最低版本根据项目需要配置。

上述配置同步之后,平常开发时,构建的速度很快,只有发布Release版本时,构建才比较慢。

缺点时,debug的APK只能安装在5.0以上的机器中(推荐Genymotion的模拟器~确实非常好用)。

3>为什么能优化速度?

上述配置完成后,gradle在构建项目时:

①APP的每个module(包含依赖)被编译为单独的dex文件,作为预编译的dex文件被引用,Android 5.0使用ART作为默认方式

②APK文件只是把每个module的dex文件包含进来,不做任何改动

③最重要的一点,所有的dex文件不用再融合,这样构建系统就不用花费很长的时间去决定把哪些classes放到primary dex文件中

2.MultiDex support library的缺陷

1>APP在启动时,将dex文件安装到Data分区的过程变得复杂,如果第二个dex文件过大,可能导致ANR错误。如果出现这种情况,可以通过ProGuard来减小dex文件的大小,同时删除没有引用的代码

2>APP 不能在低于Android 4.0的版本启动

3>使用MultiDex机制的APP如果在运行时申请过大的内存,可能导致APP crash,因为Android 5.0之前的版本限制了Dalvik能够申请的内存

4>Dalvik虚拟机在运行时,对于哪些需要放在primary dex文件的class的需求时非常复杂的,有可能某些需要的类库并没有被放在primary dex文件中,导致运行时错误

四、参考资料

参考网址:

https://developer.android.com/tools/building/multidex.html#avoid

http://stackoverflow.com/questions/32205938/java-lang-noclassdeffounderror-android-support-v4-view-layoutinflatercompathc-i

http://frogermcs.github.io/MultiDex-solution-for-64k-limit-in-Dalvik/


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:45次
    • 积分:10
    • 等级:
    • 排名:千里之外
    • 原创:1篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章存档