升級Gradle3.0
業(yè)精于勤荒于嬉,行成于思毀于隨
Android Gradle 3.0.0插件是一個大版本的升級柒莉,對于構(gòu)建多個module帶來了顯著的性能提升。但同時也更新了DSL和APIS。
升級Gradle3.0所帶來的好處如下:
- 通過細粒度的任務圖更好地實現(xiàn)多模塊項目的并行性
- Variant-aware dependency management (變體感知的依賴管理)
- 可以使用Gradle的新依賴項配置來限制哪些依賴項將其API泄漏到其他模塊:implementation,api愉粤,compileOnly和runtimeOnly。從而增加構(gòu)建速度拿撩。
- 使用 per-class dexing 加快增量構(gòu)建速度衣厘。每個類被編譯成一個獨立的dex文件,并且只有這個類被修改后才會重新編譯压恒。
升級步驟
升級Gradle版本影暴。在gradle/wrapper/gradle-wrapper.properties
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
升級Android Gradle Plugin版本。在工程的build.gradle
classpath 'com.android.tools.build:gradle:3.1.3'
新的依賴配置
新配置 | 棄用 | |
---|---|---|
implementation | compile | 在編譯時探赫,該模塊的依賴不會泄露給其他模塊坤检。只有在運行時其他模塊才能獲取依賴。 |
api | compile | 不論是在編譯時期吓,還是在運行時,其他模塊都可以獲得這個依賴倾芝。 |
compileOnly | provided | 依賴項僅在編譯時對模塊可用讨勤,并且在編譯或運行時對其消費者不可用。 此配置的行為類似于 provided (現(xiàn)在已棄用)晨另。 |
runtimeOnly | apk | 依賴項僅在運行時對模塊及其消費者可用潭千。 此配置的行為類似于 apk (現(xiàn)在已棄用)。 |
升級Gradle3.0問題匯總
此處總結(jié)我在升級公共庫和項目的gradle版本時借尿,所遇到的問題刨晴。
問題一
- Gradle 3.0 API更新較多屉来。例如,PrepareLibraryTask等類被移除掉
解決方式
把移除掉的類全部拿過來狈癞,放在本地茄靠。將gradle2.3的PrepareLibraryTask挪到本地。
注意問題
- 在gradle2.3中的
PrepareLibraryTask
類中使用@ParallelizableTask
注解蝶桶。而在gradle3.0中該注解被刪除慨绳,可以使用WorkerExecutor
API替換。 - 在
PrepareLibraryTask
類中去掉useBuildCache相關(guān)代碼
問題二
Cannot invoke method doLast() on null object
對這個task做判空操作真竖。
問題三
Error:Unable to resolve dependency for ':app@debug/compileClasspath': Could not resolve project :library
使用變體的依賴關(guān)系解決方案脐雪,您不再需要使用特定于變體的配置(例如freeDebugImplementation)來獲取本地模塊依賴關(guān)系 - 插件會自動提供配置。
// implementation project(path: ":dcsdk",configuration:'debug')
implementation project(":dcsdk") // 用這種替換
問題四
Resolving configuration 'provided' directly is not allowed
解決方案
設(shè)置setCanBeResolved(true)恢共,剛開始并沒有作用战秋。后來發(fā)現(xiàn),主項目是通過jar包的形式加載bytePlugin插件讨韭。雖然修改了代碼脂信,但是并沒有打包到指定位置。將其打包到指定位置拐袜,就可以解決此問題吉嚣。
問題五
java.lang.RuntimeException:com.android.builder.dexing.DexArchiveMergerException:
包重復引用。將bytecodemonitor中的
implementation fileTree(dir: 'libs', include: ['*.jar'])
修改為
compileOnly fileTree(dir: 'libs', include: ['*.jar'])
問題六
Could not resolve all dependencies for configuration ':demo:debugAndroidTestCompileClasspath'.
A problem occurred configuring project ':sdk'.
ABIs [mips64, armeabi, mips] are not supported for platform. Supported ABIs are [armeabi-v7a, arm64-v8a, x86, x86_64].
解決方案
最新的NDK r17版本蹬铺,已經(jīng)去掉了armeabi尝哆、mips、mips64的ABI支持甜攀。
去掉abiFilters中的armeabi選項
ndk {
abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
}
問題七
Caused by: org.gradle.api.internal.artifacts.ivyservice.DefaultLenientConfiguration$ArtifactResolveException: Could not resolve all files for configuration ':demo:releaseUnitTestRuntimeClasspath'.
at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.rethrowFailure(DefaultConfiguration.java:918)
at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.access$1600(DefaultConfiguration.java:116)
at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration$ConfigurationFileCollection.getFiles(DefaultConfiguration.java:892)
at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.getFiles(DefaultConfiguration.java:404)
at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration_Decorated.getFiles(Unknown Source)
at org.gradle.api.file.FileCollection$getFiles.call(Unknown Source)
at com.netease.tech.analysis.plugin.MobileAnalysisPlugin$_apply_closure2$_closure3.doCall(MobileAnalysisPlugin.groovy:53)
at sun.reflect.GeneratedMethodAccessor607.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
at groovy.lang.Closure.call(Closure.java:414)
at groovy.lang.Closure.call(Closure.java:430)
at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2040)
at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2025)
at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2078)
at org.codehaus.groovy.runtime.dgm$165.invoke(Unknown Source)
at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoMetaMethodSiteNoUnwrapNoCoerce.invoke(PogoMetaMethodSite.java:251)
at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.call(PogoMetaMethodSite.java:71)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
at com.netease.tech.analysis.plugin.MobileAnalysisPlugin$_apply_closure2.doCall(MobileAnalysisPlugin.groovy:41)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
at groovy.lang.Closure.call(Closure.java:414)
at org.gradle.listener.ClosureBackedMethodInvocationDispatch.dispatch(ClosureBackedMethodInvocationDispatch.java:40)
at org.gradle.listener.ClosureBackedMethodInvocationDispatch.dispatch(ClosureBackedMethodInvocationDispatch.java:25)
at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:42)
at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:230)
at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:149)
at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:58)
at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:324)
at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:234)
at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:140)
at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:37)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
at com.sun.proxy.$Proxy27.afterEvaluate(Unknown Source)
at org.gradle.configuration.project.LifecycleProjectEvaluator.notifyAfterEvaluate(LifecycleProjectEvaluator.java:76)
... 85 more
解決方案
問題定位到自定義插件的代碼
if (conf.isCanBeResolved()) {
f.addAll(conf.getFiles())
}
當調(diào)用conf.getFiles() 方法時秋泄,就會報錯。報錯的信息顯示规阀,Could not resolve all files for configuration':demo:releaseUnitTestRuntimeClasspath'
恒序。根據(jù)報錯信息提示,應該是解析不了releaseUnitTestRuntimeClasspath配置的一些文件谁撼。
這個問題困擾了很久歧胁,最終臨時把這些解析不了的task全部過濾掉,然后就可以正常運行了厉碟。
問題八
Error:(94, 5) style attribute '@android:attr/windowExitAnimation' not found
Error:(94, 5) style attribute '@android:attr/windowEnterAnimation' not found
解決方案
移除@喊巍,即將
<item name="@android:windowEnterAnimation">@anim/anim_toast_show</item>
<item name="@android:windowExitAnimation">@anim/anim_toast_hide</item>
改為:
<item name="android:windowEnterAnimation">@anim/anim_toast_show</item>
<item name="android:windowExitAnimation">@anim/anim_toast_hide</item>