方法数超过 64K怎么办 使用 multidex 来解决

一、前言:

在 Android 中,有一个限制,那就是整个应用的方法不能超过 65536,否则就会出现编译错误,并且程序也无法成功地安装到手机上。当项目日益庞大后这个问题就比较容易遇到,Google 提供了 multidex 方案专门用于解决这个问题,通过一个 dex 文件拆分为多个 dex 文件来避免单个 dex 文件方法数越界的问题。

使用 CrashHandler 来获取应用的 crash 信息

在 Android 中单个 dex 文件所能够包含的最大方法数是 65536,这包含了 Android FrameWork、依赖的 jar 包以及应用本身的代码中的所有方法。65536是一个很大的数,一般一个简单应用的方法很难达到65536,但是对于一些较大型的应用来说,65536 方法就很容易达到了。

异常如下:

he number of method references in a .dex file cannot exceed 64K.
Learn how to resolve this issue at https://developer.android.com/tools/building/multidex.html   
com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536 

二、解决 方法超过65536:

1. 基本配置

app中build.gradle中添加

//开启分包
multiDexEnabled true
//依赖:支持多个dex和依赖multidex库。
compile 'com.android.support:multidex:1.0.1';

apply plugin: 'com.android.application'
android {
    compileSdkVersion 27
    defaultConfig {
        applicationId "com.function.luo.demo"
        minSdkVersion 24
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
        // Enabling multidex support.
        multiDexEnabled true
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:27.1.1'
     //分包依赖
    compile 'com.android.support:multidex:1.0.1'
}

基本配置完成后,实现方案有三种方案可以选

2. 方案一:在 manifest 文件中指定 Application 为 MultiDexApplication:

如下所示:

<application
android:name="android.support.multidex.MultiDexApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        ...
</application>

3. 方案二:让应用的 Application 继承 MultiDexApplication:

如下所示:

public class MyAppliction extends MultiDexApplication {
    ...
}

4. 方案三:如果不想让应用的 Application 继承 MultiDexApplication,还可以选择重写 Application 的 attachBaseContext 方法,这个方法比 Application 的 onCreate 要先执行:

如下所示:

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

对于一个使用 multidex 方案的应用,采用了上面的配置项,如果应用的方法数没有越界,那么 Gradle 并不会生成多个 dex 文件,如果方法数越界后,Gradle 就会在 apk 中打包 2 个或多个 dex 文件,具体会打多少个 dex 文件要看当前项目代码的规模。

三、Mutlidex 可能出现的问题:

1. Mutlidex带来的局限性:

  • 应用启动速度会降低,由于应用启动时会加载额外的 dex 文件,这将导致应用的启动速度降低,甚至可能出现 ANR 现象,尤其是其它 dex 文件较大的时候,因此要避免生成较大的 dex 文件。
  • 由于 Dalvik linearAlloc 的 bug,这可能导致使用 multidex 的应用无法在 Android 4.0 以前的手机上运行,因此需要做大量的兼容性测试。也可能在应用中采用multidex方案从而产生大量的内存消耗的情况,这会导致应用的崩溃。
  • Dex文件安装到设备的过程非常复杂,如果第二个Dex文件太大,可能导致应用无响应。此时应该使用ProGuard减小Dex文件的大小。

2. 与此同时可能会报java.lang.OutOfMemoryError: Java heap space错误:

那么解决方法是:在app的build.gradle中android中添加如下代码

//加大java堆内存大小
dexOptions {
   javaMaxHeapSize "4g"//这里2g或者4g都可以
}


原文链接:https://blog.csdn.net/gongxiaoou/article/details/81281415

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章