Android Studio 升级3.x 版本填坑尝试

Android Studio 升级3.x 版本填坑尝试

下载安装最新的studio3.1.1

前言

最近在公司中把android studio 升级到版本 3.1.1 ,但是随之而来的问题一大把

首先第一个,AS 3.1.1 使用的gradle版本是 gradle-4.4-all 计入使用低于这个版本的gradle ,整个工具将会进入一种低效能的状态,朋友经常跟我抱怨,升级后的android studio 编译慢的无法忍受,其实我自己也是无法忍受的,于是抽了一下午的时间,研究了这个问题。

改善

升级gradle版本与android studio的版本对应

一、 android studio 插件无法安装

  • 这个的原因是: android studio的代理没有配置,从android studio 3.1.1之后就会出现这个问题,之前的版本没有发下这个bug

解决方案:

  • 1. 淘宝购买自己的VPN
  • 2. 安装并运行,记住这是前提
  • 3. file -> setting -> Appearance & Behavior -> HTTP Proxy -> 勾选 Manual proxy configuation -> 选择 SOCKS -> Host name 127.0.0.1 ; Port number: 1080 这个是固定的
  • 4. 重启studio
  • 5. 提示设置 https 把上面的参数同样的抄一下就可以了
  • 6. 编译后完美解决

二、sdk对应版本未安装,报错文件找不到

error: resource style/Base.V26.Widget.AppCompat.Toolbar 
(aka com.example.jhon.aaaa:style/Base.V26.Widget.AppCompat.Toolbar) not found.
  • 解决settting —>system setting —> Android SDK 下载最新的

三、org.gradle.api.GradleException: All flavors must now belong to a named flavo

这个问题是Android studio升级到3.0之后的版本,gradle 大于4.1

主程序的build.gradle中的gradle版本改成了3.0.1
 dependencies {
        classpath 'com.android.tools.build:gradle:3.0.1' 
}

提示: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

扫描二维码关注公众号,回复: 3408929 查看本文章

大致是说,Plugin 3.0.0之后有一种自动匹配消耗库的机制,便于debug variant 自动消耗一个库,然后就是必须要所有的flavor 都属于同一个维度。

但是我们从中已经知道解决方案了:

  • 在主app的build.gradle里面的

     defaultConfig {
        targetSdkVersion:***
        minSdkVersion :***
        versionCode:***
        versionName :***
        //版本名后面添加一句话,意思就是flavor dimension 它的维度就是该版本号,这样维度就是都是统一的了
        flavorDimensions "versionCode"
    }
    

就直接解决这个问题。

四、To suppress this warning, remove “buildToolsVersion ‘25.0.3’” from your build.gradle file….

The specified Android SDK Build Tools version (25.0.3) is ignored, as it is below the minimum supported version (27.0.3) for Android Gradle Plugin 3.1.1.
Android SDK Build Tools 27.0.3 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.
Update Build Tools version and sync project
Open File

这个问题是androidstudio 3.x 版本默认所有的项目使用相同的 buildTools,不需要用户单独制定项目 buildTools 的版本

解决和简单,在报错的项目中去掉 buildToolsVersion 即可

  • 2.在各个依赖的版本的build.gradle文件中去掉 下面这句

    buildToolsVersion ‘23.0.2’

五、error: style attribute ‘@android:attr/windowEnterAnimation’ not found.

报错

error: style attribute ‘@android:attr/windowEnterAnimation’ not found.

原因

  • 提示我们找不到@android:attr/windowEnterAnimation,因为已经不支持@开头使用android自带的属性,我们只要把@符号删掉就可以了。

  • 注意:网上一些解决办法是直接把aapt2给关掉,这种掩耳盗铃式的处理办法是有隐患的!类似于,你在工程里遇到空指针异常,直接try-catch而且不处理,最终的确不会因此而崩溃,但是问题解决了?!
    当你想在android studio 3.0中使用一些JRebel for Android等插件时,会导致无法使用,到处报错。本人之前就一路修复问题最终还是无法使用,最终发现是aapt的问题。

解决办法

  • 全局搜索@android:attr/windowEnterAnimation找到相应的地方,把@去除

修改前:

<style name="remnote_play_time_animation">
        <item name="@android:windowEnterAnimation">@anim/remote_play_popup_show</item>
        <item name="@android:windowExitAnimation">@anim/remote_play_popup_hide</item>
</style>

六、Android Studio3.xx新的依赖方式 implementation、api、compileOnly变化

报错:

Configuration 'androidTestCompile' is obsolete and has been replaced with 'androidTestImplementation' and 'androidTestApi'.

Android Studio3.0正式版已经出来了,相比2.x的版本,编译速度提高了不少。
当我们使用AS3.0新建项目时会发现,默认的依赖由之前的compile更改为implementation了。

  • 下面我们来看看他们之前的差异:

    首先是2.x版本的依赖方式:

    在3.0之后依赖方式变为这样了:

可以看到在Android studio3.0中,compile依赖关系已被弃用,被implementation和api替代,provided被compile only替代,apk被runtime only替代,剩下的看名字就知道了。

七、我们先来看看implementation和api的区别:

  • api:跟2.x版本的 compile完全相同

  • implementation:只能在内部使用此模块,比如我在一个libiary中使用implementation依赖了gson库,然后我的主项目依赖了libiary,那么,我的主项目就无法访问gson库中的方法。这样的好处是编译速度会加快,推荐使用implementation的方式去依赖,如果你需要提供给外部访问,那么就使用api依赖即可

  • 还不熟悉2.x版本依赖的可以看看下面的说明,括号里对应的是3.0版本的依赖方式。

    • compile(api)

      这种是我们最常用的方式,使用该方式依赖的库将会参与编译和打包。
      当我们依赖一些第三方的库时,可能会遇到com.android.support冲突的问题,就是因为开发者使用的compile依赖的com.android.support包,而他所依赖的包与我们本地所依赖的com.android.support包版本不一样,所以就会报All com.android.support libraries must use the exact same version specification (mixing versions can lead to runtime crashes这个错误。

      解决办法可以看这篇博客:com.android.support冲突的解决办法

    • provided(compileOnly)

      只在编译时有效,不会参与打包
      可以在自己的moudle中使用该方式依赖一些比如com.android.support,gson这些使用者常用的库,避免冲突。

    • apk(runtimeOnly)

      只在生成apk的时候参与打包,编译时不会参与,很少用。

    • testCompile(testImplementation)

      testCompile 只在单元测试代码的编译以及最终打包测试apk时有效。

    • debugCompile(debugImplementation)

      debugCompile 只在debug模式的编译和最终的debug apk打包时有效

    • releaseCompile(releaseImplementation)

      Release compile 仅仅针对Release 模式的编译和最终的Release apk打包。

八、Error:Failed to resolve: multidex

在2.x版本的项目依赖中,可以不明确的指定依赖库的版本号如下图

    compile 'com.android.support:multidex:+'

+表示依赖中暗影仓库中项目的最新版本

但是在3.x之后,必须注明是具体的某一个版本

implementation 'com.android.support:multidex:1.0.2'

九、依赖包报错找不到 Compilation failed; see the compiler error output for details.

Compilation failed; see the compiler error output for details.

很明显的就是没有导包的现象,这种情况多半是依赖库是通过项目中的依赖文件间接依赖导致的
解决

将子项目的依赖文件修改成 api方式依赖,这样主项目也就可以使用这个依赖了

十、 打包输出文件不通过

报错如下

    Error:(60, 0) Cannot set the value of read-only property 'outputFile' for ApkVariantOutputImpl_Decorated{apkData=Main{type=MAIN, fullName=xiaomiRelease, filters=[]}} of type com.android.build.gradle.internal.api.ApkVariantOutputImpl.
    <a href="openFile:E:\Studio\MyApplication\CodeBook\build.gradle">Open File</a>

查阅资料发现,在3.0之后 output.outputFile变成了只读属性
换句话说3.0之前apk的输出命名是这样的

applicationVariants.all { variant ->    //批量修改Apk名字
    variant.outputs.each { output ->
        def outputFile = output.outputFile
        if (outputFile != null && outputFile.name.endsWith('.apk') && 'release'.equals(variant.buildType.name)) {
            def fileName = outputFile.name.replace("${variant.flavorName}", "V${defaultConfig.versionName}-${variant.flavorName}")
            fileName = fileName.replace('.apk', "-${buildTime()}.apk")
            output.outputFile = new File(outputFile.parent, fileName)
        }
    }
}

在3.0之后 output.outputFile 只读,因此必须这样解决

applicationVariants.all { variant ->    //批量修改Apk名字
    variant.outputs.all { output ->
        if (!variant.buildType.isDebuggable()) {
            //获取签名的名字 variant.signingConfig.name
            //要被替换的源字符串
            def sourceFile = "-${variant.flavorName}-${variant.buildType.name}"
            //替换的字符串
            def replaceFile = "_V${variant.versionName}_${variant.flavorName}_${variant.buildType.name}_${buildTime()}"
            outputFileName = output.outputFile.name.replace(sourceFile, replaceFile);
            //遗留问题:如何获取当前module的name,如CodeBooke这个名字怎么获取到
        }
    }
}

当然我们的项目是这样滴

 applicationVariants.all { variant ->    //批量修改Apk名字
    variant.outputs.all { output ->
        def outputFile = output.outputFile

        if (outputFile != null && outputFile.name.endsWith('.apk')) {
            //获取签名的名字 variant.signingConfig.name
            //要被替换的源字符串
            def sourceFile = "-${variant.flavorName}-${variant.buildType.name}"
            // 输出apk名称为wooyun_v1.0_wandoujia.apk

            //替换的字符串
            def replaceFile = "zhengtu_v${defaultConfig.versionName}_${variant.productFlavors[0].name}.apk"
            outputFileName = output.outputFile.name.replace(sourceFile, replaceFile);
            //遗留问题:如何获取当前module的name,如CodeBooke这个名字怎么获取到
        }
    }
}

十一、 依赖关系的改变

参考链接:https://developer.android.com/studio/build/gradle-plugin-3-0-0-migration.html?utm_source=android-studio#new_configurations

大体如下:

使用新依赖项配置
Gradle 3.4 引入了新的 Java 库插件配置,允许您控制到编译和运行时类路径的发布(适用于模块间依赖项)。 Android 插件 3.0.0 正在迁移到这些新依赖项配置。 要迁移您的项目,只需更新您的依赖项以使用新配置,而非已弃用配置,如下表中所列。

新配置 已弃用配置 行为
implementation compile 依赖项在编译时对模块可用,并且仅在运行时对模块的消费者可用。 对于大型多项目构建,使用 implementation 而不是 api/compile 可以显著缩短构建时间,因为它可以减少构建系统需要重新编译的项目量。 大多数应用和测试模块都应使用此配置。

api compile 依赖项在编译时对模块可用,并且在编译时和运行时还对模块的消费者可用。 此配置的行为类似于 compile(现在已弃用),一般情况下,您应当仅在库模块中使用它。 应用模块应使用 implementation,除非您想要将其 API 公开给单独的测试模块。
compileOnly provided 依赖项仅在编译时对模块可用,并且在编译或运行时对其消费者不可用。 此配置的行为类似于 provided(现在已弃用)。
runtimeOnly apk 依赖项仅在运行时对模块及其消费者可用。 此配置的行为类似于 apk(现在已弃用)。
就像当前稳定版本的 Android 插件一样,上面的配置对风味或构建类型特定的依赖项可用。 例如,您可以使用 api 让依赖项对所有变体可用,也可以使用 redApi 让其仅对模块的 red 变体可用。

注:compile、provided 和 apk 目前仍然可用。 不过,它们将在下一个主要版本的 Android 插件中消失。

发布依赖项

十二、 插件无法安装

  • 同样是androidstudio 并且在相同的网络环境下使用,会出现有的机器的特定版本可以下载,有的机器的版本下载不了的情况,这是因为插件和一些ide的下载都是通过国外的网站下载的,链接会不稳定
  • 最有效的解决方案就是使用梯子
  • 下面是梯子配置的步骤

1. 运行梯子

2.打开plugins的配置界面,找到如下的配置

3. browse repositories 下的HTTP Proxy Setting.. 进行如下的配置 测试链接,成功就可以下载了,爽歪歪

十三、Gradle自定义apk名称报错(无法设置只读属性’outputFile’的值)

  • AS 3.0之前自定义apk名称:

    applicationVariants.all { variant ->
        variant.outputs.each { output ->
        def fileName = "${variant.versionName}_release.apk"
        def outFile = output.outputFile
        if (outFile != null && outFile.name.endsWith('.apk')) {
            output.outputFile =newFile(outFile.parent, fileName)
        }  
    }
    
  • AS 3.0之后,同样代码自定义apk名称却会报错:

错误

    错误:(56,0)无法为com.android.build.gradle类型的ApkVariantOutputImpl_Decorated {apkData = Main {type = MAIN,fullName = debug,filters = []}}设置只读属性'outputFile'的值。 internal.api.ApkVariantOutputImpl。

解决方案

    outputFile变为只读,不能修改输出的名称所以报错修改为:
    applicationVariants.all { variant ->
        variant.outputs.all { output ->  // each 改为 all
        def fileName = "${variant.versionName}_release.apk"
        def outFile = output.outputFile
        if (outFile != null && outFile.name.endsWith('.apk')) {
            outputFileName = fileName  //  output.outputFile 改为 outputFileName 
        }    
    }

把each修改为all,然后通过outputFileName修改生成apk的名称。此外,AS 3.0后打包完,除了apk包文件,还会多一个output.json参数文件。

十四、 AAPT2编译报错

错误

  • 错误:java.util.concurrent.ExecutionException:com.android.tools.aapt2.Aapt2Exception:AAPT2错误:检查日志以获取详细信息

  • 在项目根目录下gradle.properties文件中关闭APPT2编译:

    ...
    android.enableAapt2 = false
    

十五、 PNG图片错误,AAPT错误(Facade for):无法打开PNG文件

错误

  • AAPT错误(Facade for):……无法打开PNG文件

解决方案
* 项目的应用程序下的build.gradle文件中添加下面属性:

    android{
        ...
        aaptOptions{
            cruncherEnabled = false
            useNewCruncher = false
        }
        ...
    }
  • 用来关闭AS图片PNG合法性检查的,直接不让它检查。

注意

  • 如果还是有错误,请检查:

    • 1).9.png图片放在res/drawable文件夹下
    • 2).9.png图片四边都要有黑线,确保图片是标准的.9.png图片

十六、输入法中文状态下无法选词

问题

  • AS 3.0后在输入中文时候会出现键盘不显示,无法筛选词输入中文

解决方案

  • 首先要说不是你的输入法问题,而是AS 3.0后的一个BUG,下面提供几种解决方案:
    • 1)如果你还在2.3.x的环境下开发,为了避免输入法问题,建议你暂时不要升级到3.x ;
    • 2)如果你想2.3.x升级使用3.x,那么不建议你使用2 .x的jre替换3.x的jre方式去处理输入法问题,虽然暂时可以解决输入问题,但是后面升级的时候你还得把2.x的jre换回3.x的jre,否则升级后将无法正常使用AS;
    • 3)最简单最有效的解决办法就是在使用AS的时候,切换到windows自带的中文输入法就可以正常输入中文筛选词语了,相对而言,这样方便很多。虽然没有第三方输入法用起来那么顺手,但是可以有效解决输入法问题和避免以后升级的问题;
    • 4)终极方案:升级到AS 3.1.1即可解决,AS 3.1.1已经修复了输入法中文状态下无法选词的BUG。

十七、移除无用资源问题

错误

  • 错误:删除未使用的资源需要打开未使用的代码收缩。

    android {
      ...
      buildTypes {
        debug {
            signingConfig signingConfigs.release
            debuggable true
            zipAlignEnabled true
            minifyEnabled true //是否混淆
            shrinkResources true //是否去除无效的资源文件
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }

        release {
            signingConfig signingConfigs.release      
            zipAlignEnabled true
            debuggable true
            minifyEnabled true //是否混淆
            shrinkResources true //是否去除无效的资源文件
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
      }
      ...
    }

AS 3.0.1后,如果使用shrinkResources来移除未引用资源,必须要先开启混淆minifyEnabled,才能通过资源压缩器将它们移除,否则编译会报错。

猜你喜欢

转载自blog.csdn.net/bencheng06/article/details/82049055