前段時(shí)間讀了一片文章Instant Run工作原理及用法,文章寫(xiě)的不錯(cuò),我很受啟發(fā)。引用其中一段
如果應(yīng)用的minSdkVersion小于21,可能多數(shù)的Instant Run功能會(huì)掛掉,這里提供一個(gè)解決方法,通過(guò)product flavor建立一個(gè)minSdkVersion大于21的新分支,用來(lái)debug
于是乎,為了能夠“使用多數(shù)”instant run的功能,我就在項(xiàng)目中新增了一個(gè)product flavor
productFlavors {
? ? dev {
? ? ? ? minSdkVersion 22
? ?}
}
我本來(lái)以為這樣做會(huì)加快增量打包速度,提高開(kāi)發(fā)效率。結(jié)果卻引入了一個(gè)大坑。這個(gè)大坑我是這樣跳進(jìn)去的。
很多大牛都推薦使用dagger2,看了很多資料之后我也感覺(jué)引入dagger2確實(shí)可以帶來(lái)很多好處。比如減少手動(dòng)寫(xiě)new的次數(shù),降低類與類之間的耦合度,方便以后測(cè)試等。于是我就開(kāi)始了折騰dagger2之路。當(dāng)前折騰dagger2的分支是從上面那個(gè)添加了productFlavors ----> dev的這個(gè)分支簽出的。
按照官方demo在項(xiàng)目中引入dagger2之后,打包的時(shí)候發(fā)生錯(cuò)誤。錯(cuò)誤如下
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中已經(jīng)啟用
multiDexEnabled=true
compile"com.android.support:multidex:${libraryVersion.multidex}"
2. 在自定義的Application類中復(fù)寫(xiě)attachBaseContext方法。
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
這個(gè)問(wèn)題很奇怪,因?yàn)槭孪任也⒉恢捞砑恿藀roductFlavors ----> dev之后,會(huì)導(dǎo)致ClassNotFoundException的錯(cuò)誤。于是我首先懷疑是dagger2相關(guān)配置導(dǎo)致的,畢竟網(wǎng)上很多人都說(shuō)dagger2有很多坑。但是花了好長(zhǎng)時(shí)間研究提交的代碼,經(jīng)過(guò)逐個(gè)commit代碼的分析,才發(fā)現(xiàn)原來(lái)是因?yàn)閍pp/build.gradle中的為了使用instant run的新特性。就是使用這個(gè)productFlavors ----> dev打包時(shí)才出現(xiàn)上述錯(cuò)誤的。
刪掉minSdkVersion 22之后,問(wèn)題解決。
可以正常工作的配置是
productFlavors {
dev {}
}
折騰了一大圈才發(fā)現(xiàn)這個(gè)并不是dagger2的坑。而是productFlavors相關(guān)的坑。
總結(jié)一下,
1. 雖然這篇文章Instant Run工作原理及用法寫(xiě)的確實(shí)不錯(cuò),但是我不應(yīng)該那么輕易地相信里面的每一個(gè)結(jié)論,因?yàn)樗慕Y(jié)論適用于它的開(kāi)發(fā)環(huán)境而不一定適用于我的。所以要避免照搬別人的結(jié)論。
2. 哪怕是引入一個(gè)小的功能,也要測(cè)試,測(cè)試通過(guò)之后才能合并代碼。否則很可能會(huì)因?yàn)楹喜⒘隋e(cuò)誤的代碼,把錯(cuò)誤擴(kuò)散到了其他簽出的分支。從而出現(xiàn)令人哭笑不得的錯(cuò)誤。