zoukankan      html  css  js  c++  java
  • 使用multidex解决64K方法引用的限制

    1.什么是64K方法引用的限制

       65536(64K)是单个dex(Dalvik Executable)字节码文件的可引用的方法数的最大数,包括Android framework、应用的library和自己的方法。解决这个限制的方法就是使Apk编译创建和使用多个dex字节码文件在一个Apk文件中。

    2.配置工程可以multidex

        Android5.0之前的multidex设置

          Android5.0(API 21)之前的版本使用Dalvik runtime虚拟机执行App代码,默认情况下,Dalvik限制每个Apk文件只有一个dex字节码文件。通过以下配置可以达到multidex的目的:
            1.添加以下依赖,该依赖的library会包含在primary dex 文件中,且管理对其他dex文件及其代码

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

            2.设置multiDexEnabled为true

    defaultConfig {
        ...
        minSdkVersion 21 
        targetSdkVersion 26
        multiDexEnabled true
    }

            3.配置Applicaiton,视情况选择以下三种之一

             如果你没有重载Application,在AndroidManifest.xml中配置如

    <application
        android:name="android.support.multidex.MultiDexApplication" >
        ...
    </application>

             下如果你重载了Applicaiton,选择继承如下类下

    public class MyApplication extends MultiDexApplication{}

             如果你重载了Application,并且无法继承MultiDexApplicationAndroid5.0及更改版本的multidex配置

    public class MyApplication extends SomeOtherApplication {
        @Override
        protected void attachBaseContext(Context base) {
            super.attachBaseContext(base);
            MultiDex.install(this);
        }
    }

        Android5.0(api21)及之后的版本使用ART虚拟机,ART本身支持从Apk文件中加载多个dex文件。在App安装时,ART会执行预编译,扫描classN.dex并把它们编译成一个系统可执行的.oat文件。因此,minSdkVersion为21及以上版本的,不需要配置multidex support library。只需要如下设置

    defaultConfig {
        ...
        minSdkVersion 21 
        targetSdkVersion 26
        multiDexEnabled true
    }

        这样配置后,Android构建工具会生成一个主dex文件,和classes2.dex、classes3.dex等等文件,在一个Apk文件中。在运行时,multidex APIs使用一个特别的类加载器搜索所有可用的dex文件

    3.multidex support library的局限

      multidex support library有以下已知和需要测试的局限

      1.当App在设备数据区启动时,dex文件的安装是很复杂的,如果第二个dex文件很大,可能会可能会导致ANR。你可以使用混淆来减小dex文件的大小和移除无用的代码

      2.当运行在Android5.0之前的版本时,multidex并不能很好的解决linearalloc limit这个问题,该问题在4.0(api14)中引入,但并没有完全解决。如果你想运行在Android4.0之前的版本上,最好多测试。使用混淆会减少甚至解决这个问题。

    4.声明需要在primary dex文件中的类

      当构建multidex App的每个dex文件时,构建工具会执行复杂的决策来决定哪些类需要在primary dex文件中App才能正常启动。如果有些类在启动时需要,但没有在primary dex文件中,会有java.lang.NoClassDefFoundError异常
      你可以手动的指定一些类编译在primary dex文件中,通过声明multiDexKeepFile或multiDexKeepProguard属性在build.gradle的buildTypes中
      multiDexKeepFile的使用如下

        1.首先创建文件,比如命名为multidex-config.txt,在该文件中指定包含在primary dex的类,格式为一行一个类,例如:

    com/example/MyClass.class
    com/example/MyOtherClass.class

        2.在build.gradle中配置该文件

    android {
        buildTypes {
            release {
                multiDexKeepFile file('multidex-config.txt')
                ...
            }
        }
    }

      multiDexKeepProguard参数同样对应一个文件,该文件使用和Proguard一样的格式且支持Proguard所有的语法。需要使用-keep来指定需要的类,如下:

    -keep class com.example.MyClass
    -keep class com.example.MyClassToo

        指定某个包下的类:

    -keep class com.example.** { *; }

         在build.gradle中配置

    android {
        buildTypes {
            release {
                multiDexKeepProguard file('multidex-config.pro')
                ...
            }
        }
    }

    5.优化开发构建中的multidex

      使用multidex的配置需要显著增加编译时间,为了减少在开发中编译时间,Android Studio做出了一些优化,在构建总用pre-dexing来复用multidex输出,pre-dexing依赖于ART,只能在Android5.0及以上使用,Gradle3.0插件更有pre-class dexing等优化,建议升级Android Studio到最新版本并用5.0以上的设备测试

  • 相关阅读:
    数据结构——算法之(029)( 字符串原地压缩)
    hihoCoder #1174:拓扑排序&#183;一
    POJ 3026 Borg Maze
    Remove Duplicates from Sorted List II--LeetCode
    mach-o格式分析
    otool -l 可执行文件结构
    mach-o可执行文件结果
    ios 编译版本 最低版本 运行版本 动态链接库
    关于__IPHONE_OS_VERSION_MAX_ALLOWED和__IPHONE_OS_VERSION_MIN_ALLOWED的用法
    OO真经——关于面向对象的哲学体系及科学体系的探讨(下)
  • 原文地址:https://www.cnblogs.com/minguo/p/8353739.html
Copyright © 2011-2022 走看看