花了一個早上的時間從2.2升級到3.0了,其實我以前做習慣了后臺會覺得所謂的升級,功能夠用就行,主要就是圖個穩(wěn)定。但自從做移動端后……技術迭代太快,不升級的話需要用到的東西往往用不到。下面是我為什么要升級的原因……
1.是因為2.5以后支持原生java8了,google已經(jīng)不推薦jackOptions形式使用java8了,而且jackOptions編譯非常非常慢!然后第三方java8跟項目一起做的很龐大的時候,也會出現(xiàn)一些奇怪的問題
2.編譯速度加快:詳情請看https://developer.android.com/studio/releases/gradle-plugin.html
3.fragment的優(yōu)化又有了!google一直都很重視fragment的方面優(yōu)化
4.包與包之間引用優(yōu)化了編譯速度!compile換成了別的引用方式,最后會提到
當然升級的副作用也有,下面請看我升級過程碰到的問題:
1 apkVariantData
異常:Error:Could not get unknown property 'apkVariantData' for object of type com.android.build.gradle.internal.api.ApplicationVariantImpl.
這個是因為在2.x中的getApkVariantData()函數(shù)在3.x中被修改成了getVariantData(),所以ApplicationVariantImpl類的apkVariantData屬性就不存在了;為了同時兼容2.x和3.x,這里我們使用variant.getProperty('variantData')來替換先前的variant.apkVariantData寫法。
如果你的項目沒有用到上面所說的這個東西,那么就可能是第三方gradle 插件使用了一些舊的api,就會導致報錯,比如這里就是因為apkVariantData這個指令已經(jīng)從 gradle 3.0 剔除了。
解決方法首先是看看你引用的包的最新版本有沒有適配3.0的。如果沒有,要么你去下載它的插件源碼,升級它的 gradle 插件到 3.0 ,再自己把過時的 api 換掉,要不就先暫時在項目中注釋掉相關插件代碼。
據(jù)說在Android Studio 3.0 beta 5已經(jīng)解決了這個問題
2 Android SDK Build Tools
異常:Error:The specified Android SDK Build Tools version (25.0.3) is ignored, as it is below the minimum supported version (26.0.2) for Android Gradle Plugin 3.0.0.
Android SDK Build Tools 26.0.2 will be used.
To suppress this warning, remove "buildToolsVersion '25.0.3'" from your build.gradle file, as each version of the Android Gradle Plugin now has a default version of the build tools.
一個很普通的問題,將所有項目從25.0.3都升級到26.0.2即可
3 jackOptions
異常:Warning:The Jack toolchain is deprecated and will not run. To enable support for Java 8 language features built into the plugin, remove 'jackOptions { ... }' from your build.gradle file, and add
android.compileOptions.sourceCompatibility 1.8
android.compileOptions.targetCompatibility 1.8
Future versions of the plugin will not support usage of 'jackOptions' in build.gradle.
To learn more, go to https://d.android.com/r/tools/java-8-support-message.html
刪掉jackOptions配置即可
4 flavorDimensions
異常:Error:All flavors must now belong to a named flavor dimension. Learn more at https://d.android.com/r/tools/flavorDimensions-missing-error-message.html
按照google出來的答案這么解決:
If you don't really need the mechanism, just specify a random flavor dimension:
android {
...
flavorDimensions "default"
...
}
For more information, check the
恕我見識少,我也是第一次使用flavorDimensions,查了一下flavorDimensions可以基于多個標準構(gòu)建多個版本,反正,添加default即可。
5 AAPT2
Error:java.util.concurrent.ExecutionException: com.android.tools.aapt2.Aapt2Exception: AAPT2 error: check logs for details
aapt2是支持增量編譯資源開發(fā),目前不支持Robelectric,并且在一些情況下會導致編譯失敗,此時可以選擇關閉aapt2。
在根項目的gradle.properties文件中添加android.enableAapt2=false
6 greendao
Error:Execution failed for task ':library:yaoguang.greendao:greendao'.
> org.eclipse.jdt.internal.compiler.impl.CompilerOptions.versionToJdkLevel(Ljava/lang/Object;)J
這是用到了greendao庫才出現(xiàn)的問題

升到3.0后變的規(guī)范了,現(xiàn)在是根目錄的build和app的build都需要添加這個配置了
7
| 新配置 | 對應的過時配置 | 描述 |
|---|---|---|
| implementation | compile | module編譯時可用,module的使用者運行時可用,對于大量使用library的項目,可以顯著提高編譯時間,因為它可以減少構(gòu)建系統(tǒng)重新編譯一些module.大多數(shù)app/test因為使用這種配置 |
| api | compile | module編譯時可用,module的使用者編譯和運行時可用,這個和過時的compile一樣的。一般是library模塊會使用它,如果app模塊一定要使用它,必須是在它想暴露api給test模塊使用 |
| compileOnly | provided | module 編譯時可用,但是module的使用者,在編譯和運行時均不可用。跟過時的provided一樣的。 |
| runtimeOnly | apk | module和它的使用者,運行時可用.它跟過時的apk是一樣. |
注意:compile,provided,apk 這些過時的依賴現(xiàn)在可以使用,但是在下個版本會移除,所以Google給我們一些時間使用。
我引用一下別人的解釋,寫的非常清楚:
作者:WeaponZhi
鏈接:https://juejin.im/post/59dc85ce51882569277ccdc6
7.1 api
api你可以簡單的理解為之前的compile。舉個例子,你使用api在lib.A下的build.gradle引用一個本地lib包,這里假設名為lib.A,那么當lib.B有改動的時候,重新編譯不僅會編譯lib.B,還會編譯包括lib.A的所有通過api引用它的包。使用api進行引用,相當于把lib.B對外暴露了接口,這時候,假使有一個lib.C引用了lib.A,那么lib.C是可以直接使用lib.B的代碼的。簡單的畫個圖來解釋下。

7.2 implementation
如下圖所示。implementation 引用的 lib 不會對外暴露自己的接口,也就是說,當lib.A implementation lib.B,lib.C implementation lib.A 的時候,如果lib.B發(fā)生了改變,那么只有lib.A會重新編譯,lib.C將不會編譯!這將大大減少編譯時間。

總而言之,更好的方式就是盡量使用implementation來進行依賴,這樣會大大改善工程的構(gòu)建時間,除非你明確需要向外暴露當前 lib 依賴的接口時,才需要使用 api 依賴。