Android 在 Multidex 下使用 Instant Run

Instant Run是Android studio 2.0出現的新功能,在RunDebug的時候,只有在第一次build會花費大量的時間。以後再次Run或者Debug的時候會直接更新到手機上面,這樣就能很快的顯示出變化,加快了開發效率。
Instant Run要求Gradle的版本在2.0.0以上,minSdkVersion最低爲15,最好minSdkVersion在21之上。隨着Android studio 2.0正式版上線,想正式開始使用Instant Run功能,可是卻遇到了一個問題:javascript

Instant Run is disabled: Instant Run does not support deploying build variants with multidex enabled, to a target with API level 20 or below.  To use Instant Run with a multidex enabled build variant, deploy to a target with API level 21 or higher.複製代碼

大意是開啓了multidex,SDK的最低版本要是21才能使用Instant Run。爲何會有這個問題出現呢?
要回答這個問題,先要了解下什麼是multidexhtml

Multidex

Android平臺中代碼會編譯成Dalvik Executable(DEX)文件,而DEX文件是有方法數的限制的,不能超過65536個方法,包括使用的類庫和本身寫的代碼的方法總數。65536就是64k,因此這個限制又稱爲64k限制,怎麼解決這個解決這個限制的問題呢?有兩個方案java

  1. 減小方法數
  2. 使用多個DEX文件(Multidex)

減小方法數當然是一個好方法,可是隨着App功能的增長,控制必定的方式數是件很困難的事情,所以就須要使用Multidex的方案了。
使用Multidex,須要在gradle裏面開啓Multidex的設置,開啓方式:android

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.0"

    defaultConfig {
        ...
        minSdkVersion 17
        targetSdkVersion 23
        ...
        multiDexEnabled true
    }
    ...
}複製代碼

還須要導入Multidex的依賴:app

dependencies {
  compile 'com.android.support:multidex:1.0.0'
}複製代碼

可使用兩種方式讓Apk分包。ide

  • 使用MultiDexApplication
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.example.android.jjz">
      <application ... android:name="android.support.multidex.MultiDexApplication"> ... </application>
    </manifest>複製代碼
  • Application實現分包:
    @Override
      protected void attachBaseContext(Context base) {
          super.attachBaseContext(base);
          MultiDex.install(this);
      }複製代碼

錯誤提示裏面顯示SDK大於21(Android 5.0)就能夠,Android 5.0有不同的呢?答案是ARTgradle

ART

Android runtime(ART)是管理runtime和系統服務的技術,ART和Dalvik都可以從DEX的二進程文件中運行,ART是自然地支持Multiple DEX文件,ART在安裝應用的時候掃描全部的DEX文件,編譯成一個單獨的.oat文件提供Android設備運行。更多的內容能夠看:ARTui

Android 5.0上全面支持了ART技術,所以能夠方便的使用Instant Run,一方面想使用Instant Run的強大功能,另外一方便又不能放棄低於5.0的Android設備。有沒有一種可以二者兼具的方法呢?this

Build Variant

每次調試的都更新下minSdkVersion,這樣一是使用不方便,另外是容易出錯,容易把錯誤的代碼提交到版本庫,致使沒必要要的錯誤出現,有沒有一種方式可以經過配置構建不一樣的環境,開發的時候使用Instant Run,Release的時候再支持Android 5.0如下的版本呢?這就要利用強大的gradle了。
要完成上面的任務須要使用一個功能productFlavors,productFlavors是gradle中的一個功能,能夠根據不通的配置構建出不通的APK,好比構建不一樣渠道的渠道包時會用到,通常productFlavors的DSL是這樣的:spa

android {

    productFlavors {
        flavor1 {
        }
        flavor2 {
        }
    }
}複製代碼

還須要使用另外一個就是Build Variant Build Type加上productFlavors就是Build Variant。好比通常的Build Type有兩種debugrelease。對應的Build Variant就是:

flavor1+debug
flavor1+release
flavor2+debug
flavor2+release複製代碼

利用Build Variant能夠配置不一樣的APK,設置不通的version,也能夠設置不通的minSdkVersion
首先使用productFlavors:

android {
    productFlavors {
        instant {
            minSdkVersion 21
        }
        app {
            minSdkVersion 17
        }
    }
}複製代碼

同步完gradle以後,能夠在View->Tool Windows找到Build Variants

Build Variants

對於的Build Variant:

Build Variant

選擇appDebug就能夠運行minSdkVersion等於17的Apk,選擇instantDebug就能夠運行minSdkVersion等於21的Apk,後者就是使用Instant Run功能了。

相關文章
相關標籤/搜索