Android 方法数 65k 问题

记录今天解决的BUG问题

Android 方法数 65k 问题

  1. 什么是方法数 65k 问题?
    在 Andorid 中单个 dex 文件所能包含的最大方法数为 65536,这包含 Android FrameWork、依赖的 jar 包以及应用本身的代码中所有的方法,当应用的方法达到 65536 后,编译器就无法完成编译,会抛出异常
trouble writing output:
Too many field references: 131000; max is 65536.
You may try using --multi-dex option.
  1. 为什么会出现这个异常?
    这个异常是 Android 应用的方法总数限制造成的。Android 平台的 Java 虚拟机 Dalvik 在执行 DEX 格式的 Java 应用程序时,使用原生类型 short 来索引 DEX 文件中的方法。这意味着单个 DEX 文件可被引用的方法总数被限制为 65536。通常 APK 仅包含一个 classes.dex 文件,因此 Android 应用的方法总数不能超过这个数量。

3.解决方法
有以下几种解决方法:

	 1.加大 Proguard 的力度来减小 DEX 的大小和方法数,但这是治标不治本的方案,随着业务代码的添加,方法数终究会到达这个限制;
	
	
	2.一种是插件化方案;
	
	3.谷歌提供了一个 MultiDex 的分包方案,当方法数超过 65536 的时候,生成多个 dex 文件,把应用启动时必须用到的类和该类的直接引用类放到 Main dex 中,把其他类放到 Second dex 中。当应用启动之后,动态加载 Second dex,从而避免 65k 问题(建议);

这里介绍的是Multidex分包方案

  1. 修改 Gradle 配置文件,启用 MultiDex 并包含 MultiDex 支持:
android {

    compileSdkVersion 26
    buildToolsVersion '26.0.2'

    defaultConfig {
        ...
        minSdkVersion 22
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

        //启动 MultiDex 支持
        multiDexEnabled true
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    dexOptions {
        //设置虚拟机堆内存大小,避免编译期间OOM,一般设置4g就够了
        javaMaxHeapSize "4g"
    }

}
    ...

    dependencies { 
    ...
    //使用google提供的分包库
    implementation 'com.android.support:multidex:1.0.2'
    implementation 'com.android.support:multidex-instrumentation:1.0.2'
    ...
}

  1. 让应用支持多 DEX 文件,在官方文档中描述了三种可选方法:

//

// 1. 在 AndroidManifest.xml 的 application 中声明 android.support.MultiDex.MultiDexApplication;
<?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.example.android.MultiDex.myapplication">
        <application
        ...
        android:name="android.support.MultiDex.MultiDexApplication">
        ...
        </application>
    </manifest>

// 2.如果你已经有自己的 Application 类,让其继承 MultiDexApplication;
public class MyApplication extends MultiDexApplication {

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
    }
}
//3. 如果你的 Application 类已经继承自其它类,你不想/能修改它,那么可以重写 attachBaseContext() 方法: 并在 AndroidManifest 中添加以下声明:

@Override 
protected void attachBaseContext(Context base) {
    super.attachBaseContext(base);
    MultiDex.install(this);
}

<?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.example.android.MultiDex.myapplication">
        <application
        ...
        android:name="android.support.MultiDex.MultiDexApplication">
        ...
        </application>
    </manifest>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值