解决方法数越界的问题

在Android中单个dex文件所能包含的最大方法数是65536,这包含AndroidFrameWork、依赖的jar包以及应用本身的代码所包含的方法。一般来说,一个简单的应用的方法数很难达到65536,但对于一些大型项目来说,就很容易达到了。当应用的方法数达到65536时,编译器就无法完成编译工作并抛出DexIndexOverflowException异常。
还有一种情况,有时候方法数并未达到65536,并且编译器也正常完成了编译工作,但是应用在低版本手机上安装异常终止。异常信息如下:

E/dalvikm: Optimization failed
E/installd:  dexopt failed on '/data/dalvik-cache/data@app@com.ryg.multidextest-2.apk@classes.dex' res = 65280

出现这种情况的原因呢,是由于dexopt是一个程序,应用在安装时,系统会通过dexopt来优化dex文件,在优化过程中dexopt采用一个固定大小的缓冲区来存储应用中所有的方法信息,这个缓冲区就是LinearAlloc。LinearAlloc缓冲区在新版本的Android系统中其大小是8MB或者16MB,但是在Android2.2和2.3中只有5MB。当待安装的apk中的方法数比较多时,尽管它还没有达到65536这个上限,但他的存储空间仍然有可能超过5MB,这种情况下dexopt程序就会报错,从而导致安装失败,这种情况主要在2.x系列的手机上出现。
不管是编译方法数越界还是安装时的dexopt错误,他们都给开发过程带来了很大的困扰。为了解决这个问题,Google在2014年提出了multidex的解决方案。
multidex在Android Studio如何使用:
首先在app目录下的build.gradle文件中添加multiDexEnabled true这个配置项:

   defaultConfig {
        applicationId "com.example.myapplication"
        minSdkVersion 19
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        
        multiDexEnabled true
    }

然后在dependencies中添加multidex的依赖:

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:28.0.0-beta01'

    implementation 'com.android.support:multidex:1.0.0'
}

最后需要在代码中加入支持multidex功能,这个过程有三种方案可选:
1、在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>

2、让应用的Application继承MultiDexApplication;

public class TestApplication extends MultiDexApplication {
  ...
}

3、如果不想让应用的Application继承MultiDexApplication,还可以选择重写Application的attachBaseContext方法,这个方法比Application的onCreate要先执行;

public class TestApplication extends Application {

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

完成上述几个步骤,可以防线应用不但编译通过并且还可以在Android2.x手机上正常安装了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值