編輯:關於Android編程
隨著Android平台的發展,Android應用的大小也變得越來越大。當你的應用和依賴庫達到某一個大小時,你會遇到構建錯誤,提示你的應用達到了Android應用構建結構的一個限制,早期構建系統的版本會報如下的錯誤:
Conversion to Dalvik format failed:
Unable to execute dex: method ID not in [0, 0xffff]: 65536
最近的Android構建系統展示一種不同的錯誤,但是是同一種問題的表象:
trouble writing output:
Too many field references: 131000; max is 65536.
You may try using –multi-dex option.
這兩種錯誤都展示了一個相同的數字:65536。這個數字很重要,他表示了一個單獨的dex字符碼文件可以調用的方法的總數。如果你構建Android應用時收到了這個錯誤,那麼恭喜你,你有很多的代碼。這個文件告訴你如何越過這個限制,繼續構建你的應用。
Note: The guidance provided in this document supersedes the guidance given in the Android Developers blog post Custom Class Loading in Dalvik.
Android的apk文件包含可執行的字符碼文件,這些文件以dex格式的形式存在,包含了用來運行應用的編譯代碼。dex文件的規范限制了一個單獨的dex文件所有可依賴的方法數為65536,包含了Android框架方法、依賴庫方法、和你自己代碼裡面的方法。在計算機科學的概念裡,這個詞語K表示1024,或者是2^10。因為65536是64x1024,這個限制也被稱作64k方法限制。
越過這個限制需要你配置應用的構建過程,來產生多個dex文件,被稱作多dex配置。
Android5.0(API 21)以前的版本使用Dalvik運行時來運行應用代碼。默認情況下,Dalvik限制每個應用一個單獨的dex文件。為了越過這個限制,你可以使用多dex依賴庫multidex support library,變成應用中主dex文件的一部分,管理添加dex文件和他們包括的代碼。
Note: If your project is configured for multidex with minSdkVersion 20 or lower, and you deploy to target devices running Android 4.4 (API level 20) or lower, Android Studio disables Instant Run.
5.0及以上版本的多dex支持
Android5.0(API 21)及以上使用ART,原生就支持從apk中多dex文件加載。ART在應用安裝的時候采用預編譯,會掃描所有的dex文件,然後把他們編譯到一個oat文件中,讓Android設備執行。
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.
避免64K限制
在配置你的應用可以使用64k或更多的方法數之前,你應該減少你代碼裡面方法的個數,包括你的代碼中定義的方法和包含的庫文件。下面的策略可以幫你避免觸碰到dex文件限制。
查看應用直接和傳遞的依賴。確保你添加的任何大的依賴庫在添加時要好過把所有代碼加進去的總和。一個常見的反例就是包括一個大的依賴庫,但是只有一小部分的工具類方法是有用的。減少你的應用代碼依賴可以幫助你避免dex限制。 使用ProGuard移除未使用的代碼,為你的應用配置ProGuard設置,然後運行ProGuard,確保混淆適用於開放版本。使用混淆確保你沒有把未使用的代碼放入apk中。
使用這些技巧可以幫你避免構建配置時需要更多的方法。這些方法同樣可以減少apk的體積,對於推廣成本大的市場是很重要的。
通過Gradle配置多dex
在Android SDK Build Tools 21.1及更高版本中的Android的Gradle插件在構建配置中支持多dex。確保你更新了Android SDK Build Tools和Android Support Repository 是最新版本。
設置你的應用項目使用多dex需要你對項目做一些修改。你需要做以下幾步:
改變Gradle構建來支持多dex 修改Manifest,依賴 MultiDexApplication類
修改
build.gradle 來包括依賴庫,使用多dex輸出,如以下截圖:
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'
}
在manifest裡面從多dex依賴包中添加MultiDexApplication到應用元素中。
...
當這些配置信息添加到應用中,Android build tools構建一個主dex(classes.dex)和支持dex(classes2.dex,classes3.dex)。構建系統最後發布時會把這些打包到apk文件中
Note: If your app uses extends the Application class, you can override the attachBaseContext() method and call MultiDex.install(this) to enable multidex. For more information, see the MultiDexApplication reference documentation.
多dex依賴庫的限制
多dex依賴庫有一些常見的限制,當你將他們納入你的應用構建系統時應該知曉這些。
在啟動過程中dex文件安裝到設備數據上是很復雜的,如果二級dex文件非常大會導致ANR。在這種情況下,你應該使用Proguard的縮包技巧來縮小dex文件的體積,移除未使用的代碼。 由於Dalvik linearAlloc的bug,使用多dex的應用可能不會在Android4.0以前的設備啟動。如果你的目標是14以前的,確保在那些啟動或者加載特定的部分類中出現問題的版本上做好測試。壓縮代碼可以減少或者消除這些潛在的問題。 由於Dalvik linearAlloc的bug,使用了多dex配置的應用匯占據很大的內存,在運行時容易崩潰。這個占用限制在Android4.0(API 14)增大了,但是應用仍然容易在Android5.0(API 21)以前的Android版本到達這個限制。 考慮到運行時在主dex文件中需要哪些類會有很多復雜的需求。Android構建工具控制Android的需求,但是很有可能其他包含了依賴包的又有額外的依賴需求包括自己檢查和native代碼的調用。有些依賴庫無法使用,只有多dex構建工具更新到允許你指定那些需要包括入主dex的類。
優化多dex構建
一個多dex配置需要明顯增加的構建時間,因為構建系統需要做很復雜的判斷,決定哪些類必須進入主dex文件,哪些類可以進入二級dex文件。這個意味著路線構建占據了一部分的發展過程,多dex明顯的變長,很有可能減慢發展過程。
為了減緩構建輸出過程的時間變長,通過使用productFlavors創建兩個構建輸出,一個開發輸出,一個產品輸出。
對於開發輸出,設置最小的SDK版本是21。這個設置在ART的格式下產生多dex文件更快。對於產品輸出,設置最小的sdk版本來匹配實際需要的版本。這種設置可以生成適配更多設備的多dex的apk文件,但是花費更多的時間去創建。
以下的構建配置例子演示了如何在Gradle文件中設置這些輸出:
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'
}
當你完成這些配置更改之後,你可以使用
devDebug 變量,這個結合了dev和debug的屬性。使用這個創建一個proguard失效、多dex生效、最小版本21的debug應用,這些配置導致Gradle作如下事情:
構建應用中每一個模塊作為獨立的dex文件。這個稱作預dex 將每個dex文件包入apk中,不做更改 最重要的是,這些dex文件不會被結合,所以這些花費長時間計算那些屬於主dex的內容的過程會避免。
這些配置導致快速的增加構建,因為只有那些修改過的模塊的dex文件會重新計算重新打包進apk中。由這些構建產生的apk文件只能在Android5.0以上的設備上測試。然而,由於執行這些配置作為一個輸出,你保留了執行包括發布版本和proguard設置的正常構建的能力。
你也能構建其他變量,包括prodDebug 變量構建,花費更長的構建時間,但是可以用於開發測試之外的。
prodRelease 變量是最後的測試和發布版本。如果你通過命令行來執行Gradle命令,你可以使用DevDebug來執行,如
./gradlew installDevDebug 更多的構建任務,可以去看Gradle構建指導。
Tip: You can also provide a custom manifest, or a custom application class for each flavor, allowing you to use the support library MultiDexApplication class, or calling MultiDex.install() only for the variants that need it.
在Android Studio中使用構建變量
構建變量在管理使用多dex的構建過程非常有用。Android Studio 允許你在UI中選擇構建變量。
在你的app中使用devDebug構建變量:
從左側打開構建變量窗口,選項在最喜歡的下面。 點擊構建變量,選擇一個不同的變量
Note: The option to Z喎?/kf/ware/vc/" target="_blank" class="keylink">vcGVuIHRoaXMgd2luZG93IGlzIG9ubHkgYXZhaWxhYmxlIGFmdGVyIHlvdSBoYXZlIHN1Y2Nlc3NmdWxseSBzeW5jaHJvbml6ZWQgQW5kcm9pZCBTdHVkaW8gd2l0aCB5b3VyIEdyYWRsZSBidWlsZCBmaWxlIHVzaW5nIHRoZSBUb29scyAmZ3Q7IEFuZHJvaWQgJmd0OyBTeW5jIFByb2plY3Qgd2l0aCBHcmFkbGUgRmlsZXMgY29tbWFuZC48L2NvZGU+PC9jb2RlPjwvY29kZT48L2NvZGU+PC9jb2RlPjwvY29kZT48L2NvZGU+PC9wPg0KPC9ibG9ja3F1b3RlPg0KPGgzIGlkPQ=="測試多dex應用">
測試多dex應用
當使用設備測試多dex應用時,額外的配置需要激活。因為類中代碼的位置不是在一個獨立的dex文件中,設備測試不會允許的很准確除非配置了多dex。
測試多dex應用,從多dex支持庫中配置MultiDexTestRunner 。如下的
build.gradle 演示了如何配置參數。
android { defaultConfig { ... testInstrumentationRunner "com.android.test.runner.MultiDexTestRunner" } }
Note: With Android Plugin for Gradle versions lower than 1.1, you need to add the following dependency for multidex-instrumentation:
dependencies { androidTestCompile('com.android.support:multidex-instrumentation:1.0.1') { exclude group: 'com.android.support', module: 'multidex' } }
你可以使用設備測試來直接或者擴展來適應你的測試用例。可選擇的,你可以復寫
onCreate 如下:
public void onCreate(Bundle arguments) { MultiDex.install(getTargetContext()); super.onCreate(arguments); ... }
Note: Use of multidex for creating a test APK is not currently supported.
翻譯自:https://developer.android.com/studio/build/multidex.html?hl=zh-cn
在android開發中,用戶能夠撥打電話是最基本的需求。俗話說“條條大路通羅馬”,實現撥打電話的方式有多種,今天,就提供最常用兩種。 首先,撥打電話,對於用戶來說,是一
Android中有兩種主要方式使用Service,通過調用Context的startService方法或調用Context的bindService方法,本文只探討純bin
概述Healthd是android4.4之後提出來的一種中介模型,該模型向下監聽來自底層的電池事件,向上傳遞電池數據信息給Framework層的BatteryServic
微信6.0主界面:(1)整體采用垂直的LinearLayout線性布局(2)最上面是ActionBar,搜索框SearchView,Overflow(含有4個單選菜單項)