前段時間讀了一片文章Instant Run工作原理及用法,文章寫的不錯,我很受啓發。引用其中一段
如果應用的minSdkVersion小於21,可能多數的Instant Run功能會掛掉,這裏提供一個解決方法,通過product flavor建立一個minSdkVersion大於21的新分支,用來debug
於是乎,爲了能夠“使用多數”instant run的功能,我就在項目中新增了一個product flavor
productFlavors {
dev {
minSdkVersion 22
}
}
我本來以爲這樣做會加快增量打包速度,提高開發效率。結果卻引入了一個大坑。這個大坑我是這樣跳進去的。
很多大牛都推薦使用dagger2,看了很多資料之後我也感覺引入dagger2確實可以帶來很多好處。比如減少手動寫new的次數,降低類與類之間的耦合度,方便以後測試等。於是我就開始了折騰dagger2之路。當前折騰dagger2的分支是從上面那個添加了productFlavors ----> dev的這個分支簽出的。
按照官方demo在項目中引入dagger2之後,打包的時候發生錯誤。錯誤如下
E/AndroidRuntime(26472): java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/multidex/MultiDex;
E/AndroidRuntime(26472): at cn.com.nggirl.nguser.app.App.attachBaseContext(App.java:135)
...
E/AndroidRuntime(26472): Caused by: java.lang.ClassNotFoundException: Didn't find class "android.support.multidex.MultiDex" on path: DexPathList[[zip file "/data/app/cn.com.nggirl.nguser.debug-1/base.apk"],nativeLibraryDirectories=[/data/app/cn.com.nggirl.nguser.debug-1/lib/arm, /vendor/lib, /system/lib]]
...
E/AndroidRuntime(26472): Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available
我的dagger2的配置如下
1. 在build.gralde中
classpath'com.neenbedankt.gradle.plugins:android-apt:1.8'
2. 在app/build.gradle中
applyplugin:'com.neenbedankt.android-apt'
...省略其他配置
// Dagger2
compile'com.google.dagger:dagger:2.7'
apt'com.google.dagger:dagger-compiler:2.7'
compile'org.glassfish:javax.annotation:10.0-b28'
我的multiDex配置如下
1. 而且app/build.gradle中已經啓用
multiDexEnabled=true
compile"com.android.support:multidex:${libraryVersion.multidex}"
2. 在自定義的Application類中複寫attachBaseContext方法。
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
這個問題很奇怪,因爲事先我並不知道添加了productFlavors ----> dev之後,會導致ClassNotFoundException的錯誤。於是我首先懷疑是dagger2相關配置導致的,畢竟網上很多人都說dagger2有很多坑。但是花了好長時間研究提交的代碼,經過逐個commit代碼的分析,才發現原來是因爲app/build.gradle中的爲了使用instant run的新特性。就是使用這個productFlavors ----> dev打包時纔出現上述錯誤的。
刪掉minSdkVersion 22之後,問題解決。
可以正常工作的配置是
productFlavors {
dev {}
}
折騰了一大圈才發現這個並不是dagger2的坑。而是productFlavors相關的坑。
總結一下,
1. 雖然這篇文章Instant Run工作原理及用法寫的確實不錯,但是我不應該那麼輕易地相信裏面的每一個結論,因爲它的結論適用於它的開發環境而不一定適用於我的。所以要避免照搬別人的結論。
2. 哪怕是引入一個小的功能,也要測試,測試通過之後才能合併代碼。否則很可能會因爲合併了錯誤的代碼,把錯誤擴散到了其他簽出的分支。從而出現令人哭笑不得的錯誤。