android 方法数越界问题 65536(方法数超过65535)
Android中单个dex文件所能够包含的最大方法数为63356,包含frameWord、依赖的jar包以及应用本身的代码中所有的方法。一般引用很难达到65536,但是对于大型应用就很容易(目前项目里有3个原生及4个h5系统)。当应用的方法数到达65536(超过65535),编译器就无法完成编译工作并抛出类似下面的异常:
com.android.dex.DexIndexOverflowException:method IDnotin[0,0xffff]:65536
或者
trouble weriting output:
Too many field references:131000;max is 65536.
You may try using --multi-dex option
google在2014年提出multidex的解决方案,通过multidex可以很好的解决方法越界的问题,并且使用起来非常简单
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
applicationId "com.hj.test.test"
minSdkVersion 15
targetSdkVersion 26
versionCode 1
versionName "1.0"
multiDexEnabled true //第一步
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(include: ['*.jar'],dir: 'libs')
compile 'com.android.support:appcompat-v7:22.1.1'
compile 'com.android.support:multidex:1.0.0' //第二步
}
第三步有三个方案可以选择(任选一种)
第三步中第一种方案,在manifest文件中指定Application为MultiDexApplication(这种在项目中没有自定义Application时使用,因为通常都会自定义Application,所以这种方法不怎么用),代码如下
<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">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
第三步中第二种方案,让应用中自定义的Application继承MultiDexApplication,比如:
public class MyApp extends MultiDexApplication {
...
}
然后Application的name属性,指向自定义的Application
<application
android:name="com.*.*.MyApp" <!--添加这句话,*为自己的包名-->
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">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
第三步中第三种方案,如果不想让应用的Application继承MultiDexApplication,还可以选择重写Application的attachBaseContext方法,这个方法比Application的onCreate要先执行,如下所示。
public class MyApp extends Application {
...
@Override
protected void attachBaseContext(Context context) {
super.attachBaseContext(context);
MultiDex.install(this);
}
}
然后Application的name属性,指向自定义的Application
<application
android:name="com.*.*.MyApp" <!--添加这句话,*为自己的包名-->
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">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
至此,65536问题得以解决,如果对您有帮助,请给个赞,谢谢!