[TOC]
2017年11月初升级Android Studio到3.0.0, 这个版本的as进行了多项更新, 新增了不少功能,比如: 支持java8,kotlin等等, 并且对gradle也升级到了4.1,加快了编译的速度等等(Android Studio Release Notes). 于是笔者对AS升级3.0,gradle插件升级到了4.1进行了测试,没有发现不好用的地方(as1.5升级到2.0时测试jni编程不如1.5), 升级过程中遇到一些问题, 结合gradle的认识和网络上搜索的结果,整理了一份升级日志, 不当之处请读者多指教.
All flavors must now belong to a named flavor dimension.
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
Gradle 4.1需要为每个渠道配置dimension, 默认可以在default
中简单的指定即可(flavor默认使用default的配置)
android {
defaultConfig {
flavorDimensions "mcpe"
}
}
当然还可以每个flavor单独覆盖
mcpe1010 {
applicationId "com.mojang.minecraftpe11"
versionCode 871010000
versionName "1.1.0"
flavorDimensions "mcpe1.1.0"
}
test1 {
applicationId "com.test"
versionCode 100
versionName "0.2.0"
flavorDimensions "mcpetest"
}
Cannot set the value of read-only property 'outputFile' for ApkVariantOutputImpl_Decorated
//2.14.1
applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.apk')) {
def flavor = variant.productFlavors[0]
def versionName = (flavor.versionName == null ? defaultConfig.versionName : flavor.versionName)
def fileName = "mcpetool_v${versionName}_${flavor.name}.apk"
output.outputFile = new File(outputFile.parent + "/apk", fileName)
}
}
}
//4.1
applicationVariants.all { variant ->
variant.outputs.all { output ->
def outputFile = output.outputFile
println "output file : ${outputFile}"
def flavor = variant.productFlavors[0]
def versionName = (flavor.versionName == null ? defaultConfig.versionName : flavor.versionName)
outputFileName = "mcpetool_v${versionName}_${flavor.name}.apk"
}
}
output.outputFile
指输出文件, 4.1使用outputFileName
指定输出文件名,位置在${module}/build/outputs/apk/${flavor.name}
Annotation processors must be explicitly declared now.
> Annotation processors must be explicitly declared now. The following dependencies on the compile classpath are found to contain annotation processor. Please add them to the annotationProcessor configuration.
- butterknife-7.0.1.jar (com.jakewharton:butterknife:7.0.1)
Alternatively, set android.defaultConfig.javaCompileOptions.annotationProcessorOptions.includeCompileClasspath = true to continue with previous behavior. Note that this option is deprecated and will be removed in the future.
See https://developer.android.com/r/tools/annotation-processor-error-message.html for more details.
- ButterKnife该升级了
com.jakewharton:butterknife:7.0.1 => com.jakewharton:butterknife:8.4.0
如果需要指定Annotation processors
:
dependencies{
annotationProcessor 'com.jakewharton:butterknife-compiler:8.4.0'
compile 'com.jakewharton:butterknife:8.4.0'
}
注: butterknife:8.4.0
中移除了ButterKnife.unbind(Context)
- 使用传统的方式处理注解,错误提示中已经有解决方法了
set android.defaultConfig.javaCompileOptions.annotationProcessorOptions.includeCompileClasspath = true
android{
defaultConfig{
//...
javaCompileOptions {
annotationProcessorOptions {
includeCompileClasspath true
}
}
}
//...
}
butterknife:7.0.1和butterknife:8.4.0差别挺大的, 比如7.0.1中的Bind注解已经没了,取代的是BindXxx(如BindView)
这种情况使用butterknife:8.4.0无疑需要对整个工程中的代码都替换一遍, 代价太高. 还有一种kotlin的解决方法是升级到新版butterknife后使用导入别名:
import butterknife.BindView as Bind
这种方法如果原先使用的是java,转化成kotlin也是一个庞大的工程.
- 最新butterknife版本为8.8.1, https://github.com/JakeWharton/butterknife
Error:The specified Android SDK Build Tools version (23.0.2) is ignored
Error:The specified Android SDK Build Tools version (23.0.2) 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 '23.0.2'" from your build.gradle file, as each version of the Android Gradle Plugin now has a default version of the build tools.
buildToolsVersion
设为26.0.2(Gradle Plugin3.0开始可以不需要指定buildToolsVersion, 会自动配置所需的最低版本), Gradle Plugin
设为3.0.0
Error:Failed to resolve: com.android.support:multidex:1.0.2
<a href="add.google.maven.repository">Add Google Maven repository and sync project</a>
//root project's build.gradle
buildscript {
repositories {
mavenCentral()
jcenter()
google()//add this
}
}
allprojects{
repositories {
jcenter()
google()//add this
}
}
style attribute '@android:attr/windowExitAnimation' not found.
网上的做法基本是gradle.properties里面加入android.enableAapt2=false, 禁用aapt2(新功能基本是要取代旧的功能,不建议直接禁用,先尝试着去修复,不行再禁掉, 最好能了解原理结合项目做出适当的调整). 笔者这里找出错的代码进行修复:
<style name="Xxx" parent="@android:style/Animation.Dialog">
<item name="@android:windowEnterAnimation">...</item>
<item name="@android:windowExitAnimation">...</item>
</style>
这种声明在之前的版本没有报错可能是个bug, 修正后是
<style name="Xxx" parent="@android:style/Animation.Dialog">
<item name="android:windowEnterAnimation">...</item>
<item name="android:windowExitAnimation">...</item>
</style>
打包签名
升级后打签名包时强制需要选择一种签名方式(V1:Jar signature V2:Full Apk signature)
V2的介绍摘自中文官网
Android 7.0 引入一项新的应用签名方案 APK Signature Scheme v2,它能提供更快的应用安装时间和更多针对未授权 APK 文件更改的保护。在默认情况下,Android Studio 2.2 和 Android Plugin for Gradle 2.2 会使用 APK Signature Scheme v2 和传统签名方案来签署您的应用。
虽然我们建议您对您的应用采用 APK Signature Scheme v2,但这项新方案并非强制性的。如果您的应用在使用 APK Signature Scheme v2 时不能正确开发,您可以停用这项新方案。禁用过程会导致 Android Studio 2.2 和 Android Plugin for Gradle 2.2 仅使用传统签名方案来签署您的应用。要仅用传统方案签署,打开模块级 build.gradle 文件,然后将行 v2SigningEnabled false 添加到您的版本签名配置中:
android { ... defaultConfig { ... } signingConfigs { release { storeFile file("myreleasekey.keystore") storePassword "password" keyAlias "MyReleaseKey" keyPassword "password" v2SigningEnabled false } } }
注意:如果您使用 APK Signature Scheme v2 签署您的应用,并对应用进行了进一步更改,则应用的签名将无效。出于这个原因,请在使用 APK Signature Scheme v2 签署您的应用之前、而非之后使用 zipalign 等工具。
如需了解详细信息,请阅读相关的 Android Studio 文档,这些文档介绍了如何在 Android Studio 中签署应用以及如何使用 Android Plugin for Gradle 为签署应用配置构建文件。
于是做了以下的实验:
- 应用签名打包, 传统的方式:dev0, V1签名:dev1, V2签名:dev2, V1V2都签名:dev12, 测试手机先安装dev0
- Android-5.0
$ adb install -r dev1.apk
pkg: /data/local/tmp/dev1.apk
Success
$ adb install -r dev2.apk
pkg: /data/local/tmp/dev2.apk
Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES]
$ adb install -r dev12.apk
pkg: /data/local/tmp/dev12.apk
Success
- Android-7.0
$ adb install -r dev1.apk
pkg: /data/local/tmp/dev1.apk
Success
$ adb install -r dev2.apk
pkg: /data/local/tmp/dev2.apk
Success
$ adb install -r dev12.apk
pkg: /data/local/tmp/dev12.apk
Success
同过实验结合网上的解决方法:
1)只勾选v1签名并不会影响什么,但是在7.0上不会使用更安全的验证方式
2)只勾选V2签名7.0以下会直接安装完显示未安装,7.0以上则使用了V2的方式验证
3)同时勾选V1和V2则所有机型都没问题
参考: Android Studio正式打包时遇到的Signature Version V1 V2
Error:Execution failed for task ':launcherActivity:transformNativeLibsWithMergeJniLibsForDebug'.
Error:Execution failed for task ':launcherActivity:transformNativeLibsWithMergeJniLibsForDebug'.
> More than one file was found with OS independent path 'lib/armeabi-v7a/libmcpelauncher_tinysubstrate.so'
sourceSets{
main{
jniLibs.srcDirs = ['libs']
jni.srcDirs = [] //disable automatic ndk-build call
}
}
==>
sourceSets{
main{
jniLibs.srcDirs = []
jni.srcDirs = [] //disable automatic ndk-build call
}
}
即可。参考大概整理下升级到Android Studio3.0遇到的问题
No such property: sdkHandler for class: com.android.build.gradle.AppPlugin Open File
sdkHandler 2.14.1之后貌似就没有了, 主要是用在了ndk编译中用于获取ndk路径, 完全可以使用以下更加通用的方式(因为纯java的)
def ndkDir = plugins.getPlugin('com.android.application').sdkHandler.getNdkFolder()
==>
def file = project.file("${rootProject.rootDir}/local.properties")
Properties pro = new Properties()
pro.load(new FileInputStream(file))
def ndkDir = pro.getProperty("ndk.dir")
gradle4.1升级建议
-
修改gradle-wrapper.properties
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
-
Android gradle plugin升级
//build.gradle buildscript { ... dependencies { classpath 'com.android.tools.build:gradle:3.0.0' } }
buildToolsVersion="26.0.2"
或者直接删除-
注解处理器修改
dependenceies{ apt ==> annotationProcessor } //保持传统的方式指定注解处理器 android{ defaultConfig{ ... flavorDimensions "any-string-you-want-here-to-specify-a-dimension" javaCompileOptions { annotationProcessorOptions { includeCompileClasspath true } } } ... }
-
check-style可能无法使用了,暂且不用,注释掉相关的插件
//apply from: '../config/quality.gradle'
这部分暂未做出修复, 然而Butterknife源码中有关于check-style在新版gradle的使用可供参考, 欢迎读者补充修正.