編輯:關於Android編程
當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的功能。
我們以APK中有兩個dex文件為例,第二個dex文件為classes2.dex。
兼容包在Applicaion實例化之後,會檢查系統版本是否支持 multidex,classes2.dex是否需要安裝。 如果需要安裝則會從APK中解壓出classes2.dex並將其拷貝到應用的沙盒目錄下。 通過反射將classes2.dex注入到當前的classloader中。下面引入一下官方的文檔。
https://developer.android.com/tools/building/multidex.html#about
筆者,針對官方文檔的翻譯如下:
隨著Android設備的慢慢發展,App的大小會變得越來越大。當我們在開發App的時候由於報的大小和引用庫的原因,我們在編譯我們項目的時候通常會遇到下面一個錯誤:
Conversion to Dalvik format failed: Unable to execute dex: method ID not in [0, 0xffff]: 65536
當然,也有一些系統設備會出現以下log信息,不過反饋的是同一個問題:
trouble writing output:
Too many field references: 131000; max is 65536.
You may try using --multi-dex option.
這兩個錯誤條件顯示一個共同的數字:65536。這個數字,它表示的是你在一個dex包中的函數方法超過了65535個。
如果你已經構建了一個Android App時,並收到了這個錯誤,那麼恭喜你,你有很多代碼!
下面我們就具體說說,如何解決這個問題。
我們知道Android中的可執行偉劍都存儲在dex文件中,其中包含已編譯的代碼來運行你的應用程序。Dalvik虛擬機對可執行dex文件的規格是有方法限制的,即一個單一的dex文件的方法總數最多為65536。
其中包括:
引用的Android Framework方法 library的方法 我們自己書寫代碼的方法。為了突破這個方法數的限制,我們就提出了一個方案——生成多個dex文件。這個多個dex文件的方案,我們又稱為multidex方案配置。
Multidex支持Android 5.0之前的版本
Android5.0版本的平台之前,Android使用的是Dalvik Runtime執行的程序代碼。默認情況下,限制應用到一個單一的classes.dex。
Dalvik字節碼文件每APK。為了繞過這個限制,你可以使用multidex支持庫,成為你的應用程序的主要部分和DEX文件進行管理,獲得額外的dex文件,它們包含的代碼。
Multidex支持Android 5.0及更高版本
Android 5.0和更高的Runtime 如art,本身就支持從應用的APK文件加載多個DEX文件。art支持預編譯的應用程序在安裝時掃描類(..)。Dex文件編譯成一個單一的Android設備上執行.oat文件。
當你確定使用multidex的分包策略的時候,請你先確定自己的代碼中都是優秀的。你還需要做以下幾步:
去掉一些未使用的import和library 使用ProGuard去掉一些未使用的代碼Android 的 Gradle插件在 Android Build Tool 21.1開始就支持使用multidex了。
設置你的應用程序開發項目中使用multidex配置,要求你做出一些修改您的應用程序開發項目。:
修改Gradle的配置,支持multidex 修改你的manifest。讓其支持multidexapplication類修改Gradle的build如下:
android {
compileSdkVersion 21
buildToolsVersion "21.1.0"
defaultConfig {
...
minSdkVersion 14
targetSdkVersion 21
...
// Enabling multidex support.
multiDexEnabled true
}
...
}
dependencies {
compile 'com.android.support:multidex:1.0.0'
}
Tips: 你可以在Gradle配置文件中的 multiDexEnabled 在 defaultConfig、
buildType、productFlavor選項設置。
在manifest文件中,添加MultidexApplication Class的引用,如下所示:
...
當然,如果你重寫了 Application,就對自定義Application的繼承方式做一個修改。
雖然我們開起來multidex是一個極好的東西,但是multidex還是存在自己的局限性,我們在開發測試之前要清楚局限性是什麼:
如果二DEX文件太大,安裝分割dex文件是一個復雜的過程,可能會導致應用程序無響應(ANR)的錯誤。在這種情況下,你應該盡量的減小dex文件的大小和刪除無用的邏輯,而不是完全依賴於multidex。 在Android 4.0設備(API Level 14)之前,由於Dalvik linearalloc bug(問題22586),multidex很可能是無法運行的。如果希望運行在Level 14之前的Android系統版本,請先確保完整的測試和使用。 應用程序使用了multiedex配置的,會造成使用比較大的內存。當然,可能還會引起dalvik虛擬機的崩潰(issue 78035)。 對於應用程序比較復雜的,存在較多的library的項目。multidex可能會造成不同依賴項目間的dex文件函數相互調用,找不到方法。一個multidex的配置,對系統apk的構建、簽名、打包復雜性大大的增加。這就意味著,你每一次的構建過程都是相當耗時的。
為了加快我們的開發速度,加快構建的過程,我們可以在Gradle productFlavors新建出來一個 development flavor 和 production flavor 來滿足我們不同構建需求。
下面是一個列子演示我們如何設置這些flavors在Gradle build文件中:
android {
productFlavors {
// Define separate dev and prod product flavors.
dev {
// dev utilizes minSDKVersion = 21 to allow the Android gradle plugin
// to pre-dex each module and produce an APK that can be tested on
// Android Lollipop without time consuming dex merging processes.
minSdkVersion 21
}
prod {
// The actual minSdkVersion for the application.
minSdkVersion 14
}
}
...
buildTypes {
release {
runProguard true
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
}
}
dependencies {
compile 'com.android.support:multidex:1.0.0'
}
在你完成了傷處的配置修改之後,你配置productFlavor 和 buildType來使用 ,devDebug 變種app。使用這些變種app,可以設置proguard disable、multidex enable方便我們測試。
這些配置需要針對Android Gradle插件做如下操作:
在分包前,編譯應用程序中的每一個module包括依賴項目,這個步驟稱為 pre-dexing。 include每一個dex文件 最重要的是,對於主dex文件,不會做切分。以保證計算速度。這樣設置既能夠保證我們的最終報是一個使用了multidex模式的,而又不影響我們平時開發的測試效率。
使用multidex工具構建變種App是非常方便的。在Android Studio允許我們選擇這種變種構建方式的接口。
使用Android Studio構建 “devDebug”構建變種app需要完成兩步:
打開變種編輯窗口,選擇favorites選項。 點擊編譯不同的變種,如下圖所示/*
* @author zhoushengtao(周聖韬)
* @since 2015年9月9日 上午 10:31:00
* @weixin stchou_zst
* @blog http://blog.csdn.net/yzzst
* @交流學習QQ群:341989536
* @私人QQ:445914891
/
版權聲明:轉載請標注:http://blog.csdn.net/yzzst 。 本文為博主原創文章,未經博主允許不得轉載。
在命令行[CMD]使用emulator.exe啟動Android模擬器兩種方式:- emulator -avd (AVD名稱)- emulator -data (鏡像文件
開發環境:android4.1.實驗功能:在第一個界面中的2個乘數輸入處分別輸入2個數字,按下結果button,會自動跳到第二個界面並顯示輸入2個數字相乘的結果。如果在第
本文實例講述了Android TabLayout(選項卡布局)簡單用法。分享給大家供大家參考,具體如下:我們在應用viewpager的時候,經常會使用TabPageInd
直接使用線程在Android開發的時候,當我們需要完成一個耗時操作的時候,通常會新建一個子線程出來,例如如下代碼new Thread(new Runnable() {