Android 遇到方法数上限65536后记录总结

前言:首先说一下我遇到的情况,最近接手了一个项目是在已有的项目里进行更新添加一些功能,然后该项目导了N多的包,在我使用Android Studio的run”App”直接安装到手机上运行是正常的,然后正式打包安装后就崩溃了,当时觉得很奇怪,然后一看日志:
trouble writing output:
Too many field references: 131000; max is 65536.
You may try using --multi-dex option.

很明显,方法数65536上限了,那为什么直接运行又没问题呢?
没办法只好查资料:
Note: While using Instant Run, Android Studio automatically configures your app for multidex when your app's minSdkVersion is set to 21 or higher. Because Instant Run only works with the debug version of your app, you still need to configure your release build for multidex to avoid the 64K limit.
大概意思就是:
如果使用Instant Run,当app的minSdkVersion大于或等于21时,Android Studio会自动配置支持multidex,但是仅debug版本有效,release版仍然需要配置multidex来突破64K限制。
原来当android sdk大于21的时候debug自动支持multidex;好了回到正文multidex分包

multidex分包

MultiDex的产生背景
当Android系统安装一个应用的时候,有一步是对Dex进行优化,这个过程有一个专门的工具来处理,叫DexOpt。DexOpt的执行过程是在第一次加载Dex文件的时候执行的。这个过程会生成一个ODEX文件,即Optimised Dex。执行ODex的效率会比直接执行Dex文件的效率要高很多。
但是在早期的android系统中,DexOpt有一个问题,DexOpt会把每一个类的方法id检索起来,存在一个链表结构里面。但是这个链表的长度是用一个short类型来保存的,导致了方法id的数目不能够超过65536个。当一个项目足够大的时候,显然这个方法数的上限是不够的。尽管在新版本的Android系统中,DexOpt修复了这个问题,但是我们仍然需要对低版本的Android系统做兼容。
为了解决方法数超限的问题,需要将该dex文件拆成两个或多个,为此谷歌官方推出了multidex兼容包,配合AndroidStudio实现了一个APK包含多个dex的功能。

MultiDex的简要原理
我们以APK中有两个dex文件为例,第二个dex文件为classes2.dex。
兼容包在Applicaion实例化之后,会检查系统版本是否支持 multidex,classes2.dex是否需要安装。
如果需要安装则会从APK中解压出classes2.dex并将其拷贝到应用的沙盒目录下。
通过反射将classes2.dex注入到当前的classloader中。
下面引入一下官方的文档:
https://developer.android.com/tools/building/multidex.html#about

好了,自己也是小白一个也不可能详细讲解MultiDex的原理,就简单粗暴的到这吧((lll¬ω¬))

MultiDex的使用
当你确定使用multidex的分包策略的时候,请你先确定自己的代码中都是优秀的。你还需要做以下几步:

  • 检查我们导入的包,去掉一些未使用的import和library,比如说使用高德定位,那我们只需导定位包就行不需要把地图等包导入
  • 检查我们自己书写的代码,将未使用的代码删掉(使用ProGuard去除未使用的方法 -为release版本配置ProGuard,能有效排除一些无用方法)
  • 检查我们自己书写的方法,尽量保证没有重复的(不要多次造同一个轮子)

上面我们已经确定后任然需要分包的话,那么久简单说下官方推荐的方法吧:

第一步:build.gradle文件中添加 一句话 multiDexEnabled = true

defaultConfig {
        applicationId "com.."
        minSdkVersion 15
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        multiDexEnabled true
    }

第二步:导入multixdex support包,用来操作引打包过程(很重要)

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

第三步:修改我们自己的Application类,使其继承 MultiDexApplication 类
你的应用中已有Application,那么可以直接将继承Application 改为继承MultiDexApplication,而无需修改manifest文件或复写attachBaseContext()方法。

//已经继承Application那么也可以通过复写attachBaseContext()方法并调用MultiDex.install(this)来支持multidex,即无需修改manifest文件
protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(this);
    }

如果之前并没有Application,那么按以下导入即可:

<?xml version="1.0" encoding="utf-8"?>
<manifest 
    <application
        ...
        android:name="android.support.multidex.MultiDexApplication">
        ...
    </application>
</manifest>

到此分包操作已经完成,我们可以正常release打包安装了。谢谢各位观看!如有错误请不吝指教。


为了向别人、向世界证明自己而努力拼搏,而一旦你真的取得了成绩,才会明白:人无须向别人证明什么,只要你能超越自己。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值