天天看點

Android Stido配置MultiDex解決65k問題

gradle配置:

android {
    ...

    defaultConfig {
        ...
        //支援multidex
        multiDexEnabled true
    }
    ...
    // 保證其他的lib沒有被preDex
    dexOptions {
        preDexLibraries = false
    }
}

dependencies {
    ...
    //支援multidex
    implementation 'com.android.support:multidex:1.0.3'
}
           

代碼配置:

第一種,Application直接繼承MultiDexApplication(針對沒有Application父類的)

public class GlobalApplication extends MultiDexApplication {
...
}
           

第二種,重寫attachBaseContext(針對已有Application父類的)

public class MyApplication extends GlobalApplication {
    ...
    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        //支援multidex
        MultiDex.install(this);
    }
}
           

使用MultiDex的最低版本要求是:

compileSdkVersion 
  buildToolsVersion "21.1.0"
           

可能遇到的問題:NoClassDefFoundError

有些類沒有直接引用而并沒有打包到dex當中導緻classes not found出錯,這是在開啟multiDex時,多個dex檔案中的類是被gradle腳本配置設定的,而且app在啟動時,首先加載的是MainDex。

Android SDK Build Tools 21.1 或者更高版本中的 Gradle Android 插件有對 multidex 的支援。這個插件使用 Proguard 來分析你的項目并在

[buildDir]/intermediates/multi-dex/[buildType]/maindexlist.txt

檔案中生成一個 app 啟動 classes 的清單。但是這個清單并不是100%準确,可能會丢失一些app啟動所需的 classes 。

有時候我們需要設定某些類被放到MainDex中避免NoClassDefFoundError錯誤, 在build.gradle中開啟multiDex,并指定配置檔案:

android {
    ...

    defaultConfig {
        ...
        //支援multidex
        multiDexEnabled true
        multiDexKeepProguard file('multiDexKeep.pro') // keep specific classes using proguard syntax
        multiDexKeepFile file('multiDexKeep.txt') // keep specific classes
    }
}
           

注意multiDexKeep.pro和multiDexKeep.txt檔案需要自己建立,放在項目的app檔案夾下

配置multiDexKeep.pro檔案(文法和proguard-rules.pro一樣,作用也是混淆相關)

-keepclassmembers class fqcn.of.javascript.interface.for.webview {  
   public *;  
} 
           

配置multiDexKeep.txt檔案,指定類即可,這個是保留在MainDex裡的類

android/support/design/widget/BaseTransientBottomBar$Behavior.class
android/support/v7/widget/RecyclerView$class
android/support/v4/app/FrameMetricsAggregator$MetricType.class
com/transitionseverywhere/Slide$GravityFlag.class
android/support/v7/view/menu/CascadingMenuPopup$class
android/support/annotation/VisibleForTesting.class
android/support/v4/media/session/MediaSessionCompatApi21.class
android/support/v4/view/ViewCompat$ViewCompatApi26Impl.class
android/support/v4/view/ViewCompat$ScrollAxis.class
android/support/v4/view/ViewCompat$ViewCompatApi19Impl.class
com/bumptech/glide/annotation/GlideType.class
           

還有一種方法是将multiDexKeep.txt放到項目的根目錄下,在根目錄的gradle中添加配置:

// 保證multidex-keep檔案中指定的檔案都加載到Main Dex中
afterEvaluate {
    tasks.matching {
        it.name.startsWith('dex')
    }.each { dx ->
        if (dx.additionalParameters == null) {
            dx.additionalParameters = []
        }
        dx.additionalParameters += '--multi-dex'
        dx.additionalParameters += "--main-dex-list=$projectDir/multidex-keep.txt".toString()
    }
}
           

繼續閱讀