Android 65k 問題

文/zerob13(簡書作者)
原文鏈接:http://www.jianshu.com/p/245022d136e1
著作權歸作者所有,轉載請聯繫作者獲得授權,並標註“簡書作者”。

在 Android 開發中,有一個之前很少聽說,最近偶爾江湖傳聞聽到過的問題,就是 65k 問題。什麼是65k問題呢?其實很簡單,就是 Android 有個限制,你的每個 App 中函數最多只能有 65536 個。

這個限制其實是這樣的,因爲在編譯成 Dalvik 字節碼,也就是把你的 Class 們生成打包到一個 classes.dex 中去的時候呢,編譯器會給你的 App 中所有的函數方法指定一個 ID, 然後每一個 classes.dex 中 ID 的範圍是 [0, 0xffff] 。 所以,你懂的,就有了那麼一個 65k 的問題。

當然大部分應用程序里路上是不會遇到這個問題的,畢竟 65k 個函數也很多了,但是考慮到現在各種引入 SDK,而且尤其是大公司的程序往往會有很多匪夷所思的功能,最後代碼越來越臃腫,指不定哪天就遇到了。不過還好,這個問題也不難解決,G社官方已經給出瞭解決方案:

multidex support library

簡單翻譯下,原理就是編譯的時候不再是單純編譯到一個 Dex 文件中去,而是切分成多個 Dex 文件。這樣每個文件都允許 65536 個函數,肯定是夠用了的。下面說下具體的操作。

首先就是導入這個庫,這個 Eclipse 和 Android Studio 不太一樣,但是具體就不說了,因爲太常見了。不過如果用的是新版本的 Android Studio 似乎已經無需導入這個庫,貌似 IDE 直接支持了。只需要把配置文件中的 multiDexEnabled 設置成 true 就可以了,大概就是下面這個樣子:

android {
   ...
   shitAppConfig {
     ...
     multiDexEnabled true
   }
}

然後就是讓你的 Application 類繼承自 MultiDexApplication 這個類 ,例如:

public class ShitApplication extends MultiDexApplication {
   ...
}

假如不方便修改繼承(比如已經繼承了其他的封裝了的 Application)那麼就稍微複雜一點,重載一下attachBaseContext,代碼如下:

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

還有一種情況就是沒有繼承過 Application 類怎麼辦?這種最方便,打開你的 AndroidMainfest 文件,在 application tag 中加入這個:

android:name="android.support.multidex.MultiDexApplication"

到此,問題算是解決了。但是這並不完美,在 Android 5.0之前,你還需要保證你的 Activity , Service等等基本上 Dalvik需要直接找你的東西都放在第一個 dex 中,否則你的 App 就會掛掉。這部分內容說起來比較複雜,我建議直接去看 Google 官方的說明,Building Apps with Over 65K Methods 。 當然,如果你的程序只支持 Android 5.0 以後的機器,那就不用擔心了,因爲 ART 會把多個 dex 合併成一個 oat 文件,就不存在找不到的問題了。

當然,真遇到這個問題的時候,還是建議看看架構上面有沒有可以改良的地方。實在不行把一個 App 拆兩個也行啊,別總想搞個大新聞,你說是吧。

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