Android Studio 3.0 升級 配置修改詳解

更新完Android Stuido 3.0 穩定版之後,打開項目會收到如下提醒


谷歌強烈建議我們更新Android Gradle Plugin 3.0 和 Gradle 4.1,所以我就習慣性的點擊了Update。  


結果……導致了一系列的修改。


1、Flavor Dimensions 配置

我的項目中用了多渠道,3.0之前配置多渠道:productFlavors配置不同的渠道包,3.0 新增了flavorDimensions的配置 

編譯的時候報錯:

Error:All flavors must now belong to a named flavor dimension. Learn more athttps://d.android.com/r/tools/flavorDimensions-missing-error-message.html


打開後面的鏈接查看原因。

Plugin 3.0.0 includes a new dependency mechanism that automatically matches variants when consuming a library. This means an app's redDebug variant will consume a library's redDebug variant. To make this work, the plugin now requires that all flavors belong to a named flavor dimension —even if you intend to use only a single dimension. Otherwise, you will get the following build error:

Error:All flavors must now belong to a named flavor dimension.
The flavor 'flavor_name' is not assigned to a flavor dimension.
Android Plugin3.0包含了一種新的依賴機制:在使用library時會自動匹配variant(debug, release),就是說app的debug會自動匹配library的debug。同樣如果使用flavor的時候,比如app的redDebug同樣會自動匹配library的redDebug。雖然有這樣的優勢,但是在使用flavor時,必須定義flavor dimension,否則會提示錯誤。


To resolve this error, assign each flavor to a named dimension, as shown in the sample below. Because dependency matching is now taken care of by the plugin, you should name your flavor dimensions carefully. For example, if all your app and library modules use the foo dimension, you'll have less control over which flavors are matched by the plugin. 

// Specifies a flavor dimension.
flavorDimensions "color"

productFlavors {
     red {
      // Assigns this product flavor to the 'color' flavor dimension.
      // This step is optional if you are using only one dimension.
      dimension "color"
      ...
    }

    blue {
      dimension "color"
      ...
    }
}
現在使用flavor,必須像上面那樣配置。


2、新的依賴配置

Gradle 3.4 推出了新的Java library plugin 配置:允許控制發佈以編譯和運行時類路徑(用於模塊間依賴)


通過下面一張圖來說明下新的Java library plugin 配置關係:


1)綠色方塊:使用者可以使用的依賴,比如:app配置library的依賴 
2)粉色方塊:組件對library:編譯時或者運行時 
3)藍色:組件內部使用,注意這裏是不用傳遞的,比如a依賴b,b依賴c, 但是a不能獲取c的配置 
4)白色:配置集成自java plugin



     
       新配置                          
對應的過時配置 
描述
implementation compile module編譯時可用,module的使用者運行時可用,對於大量使用library的項目,可以顯著提高編譯時間,因爲它可以減少構建系統重新編譯一些module.大多數app/test因爲使用這種配置
api compile module編譯時可用,module的使用者編譯和運行時可用,這個和過時的compile一樣的。一般是library模塊會使用它,如果app模塊一定要使用它,必須是在它想暴露api給test模塊使用
compileOnly provided module 編譯時可用,但是module的使用者,在編譯和運行時均不可用。跟過時的provided一樣的。
runtimeOnly apk module和它的使用者,運行時可用.它跟過時的apk是一樣.


我們需要把舊的依賴配置 compile,provided,apk 改成新的依賴配置



3、使用annotationProcessor

我的項目使用的註解插件是android-apt。

什麼是APT?

APT(Annotation Processing Tool)是一種處理註釋的工具,它對源代碼文件進行檢測找出其中的Annotation,使用Annotation進行額外的處理。 Annotation處理器在處理Annotation時可以根據源文件中的Annotation生成額外的源文件和其它的文件(文件具體內容由Annotation處理器的編寫者決定),APT還會編譯生成的源文件和原來的源文件,將它們一起生成class文件。

Android Gradle 插件提供了名爲 annotationProcessor  的功能來完全代替  android-apt ,自此android-apt  作者在官網發表聲明證實了後續將不會繼續維護  android-apt ,並推薦大家使用 Android 官方插件annotationProcessor。


切換步驟:

1.)修改Project 的build.gradle配置

android-apt方式

dependencies {
        classpath 'com.android.tools.build:gradle:2.2.3'
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
    }
修改後annotationProcessor  方式

 dependencies {
        classpath 'com.android.tools.build:gradle:3.0.0'
    }

2.)修改module的build.gradle配置

android-apt方式

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
    }
}
apply plugin: 'com.neenbedankt.android-apt'
dependencies {
    compile 'org.greenrobot:eventbus:3.0.0'
    apt'org.greenrobot:eventbus-annotation-processor:3.0.1'//apt
}
修改後annotationProcessor  方式,只保留dependencies 裏面的引用並且把apt 換成annotationProcessor就可以了
dependencies {
    compile 'org.greenrobot:eventbus:3.0.0'
    annotationProcessor  'org.greenrobot:eventbus-annotation-processor:3.0.1'
}



其他編譯錯誤

1、The specified Android SDK Build Tools version (23.0.1) 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.1'" 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


Gradle Plugin 3.0.0要求buildToolsVersion的最低版本是26.0.2


2、Error:org.gradle.process.internal.ExecException: Process 'command '/Users/chenlin/work/Android/android-sdks/build-tools/26.0.2/aapt'' finished with non-zero exit value 1


在gradle.properties中關閉APPT2編譯 : android.enableAapt2=false 


3、gradle打包,自定義apk名稱代碼報錯(Cannot set the value of read-only property ‘outputFile’ ) 
Error:(56, 0) Cannot set the value of read-only property ‘outputFile’ for ApkVariantOutputImpl_Decorated{apkData=Main{type=MAIN, fullName=debug, filters=[]}} of type com.android.build.gradle.internal.api.ApkVariantOutputImpl.


在app的buide.gradle修改3.0之前輸出自定義apk名字的代碼,代碼如下:

//            applicationVariants.all { variant ->
//                variant.outputs.each { output ->
//                    def outputFile = output.outputFile
//                    if (outputFile != null && outputFile.name.endsWith('.apk')) {
//                        // 輸出apk名稱爲1hu_v1.0_wandoujia.apk
//                        def fileName = "1hu_${defaultConfig.versionName}_${variant.productFlavors[0].name}.apk"
//                        output.outputFile = new File(outputFile.parent, fileName)
//                    }
//                }
//            }
修改爲:
            android.applicationVariants.all { variant ->
                variant.outputs.all {
                    outputFileName = "1hu_${defaultConfig.versionName}_${variant.productFlavors[0].name}.apk"
                }
            }


4、

Error:Cannot choose between the following configurations of project :Hud:

  - debugApiElements

  - debugRuntimeElements

  - releaseApiElements

  - releaseRuntimeElements

All of them match the consumer attributes:

  - Configuration 'debugApiElements':

      - Found com.android.build.api.attributes.BuildTypeAttr 'debug' but wasn't required.

      - Found com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Aar' but wasn't required.

      - Found com.android.build.gradle.internal.dependency.VariantAttr 'debug' but wasn't required.

      - Found org.gradle.api.attributes.Usage 'java-api' but wasn't required.

  - Configuration 'debugRuntimeElements':

      - Found com.android.build.api.attributes.BuildTypeAttr 'debug' but wasn't required.

      - Found com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Aar' but wasn't required.

      - Found com.android.build.gradle.internal.dependency.VariantAttr 'debug' but wasn't required.

      - Found org.gradle.api.attributes.Usage 'java-runtime' but wasn't required.

  - Configuration 'releaseApiElements':

      - Found com.android.build.api.attributes.BuildTypeAttr 'release' but wasn't required.

      - Found com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Aar' but wasn't required.

      - Found com.android.build.gradle.internal.dependency.VariantAttr 'release' but wasn't required.

      - Found org.gradle.api.attributes.Usage 'java-api' but wasn't required.

  - Configuration 'releaseRuntimeElements':

      - Found com.android.build.api.attributes.BuildTypeAttr 'release' but wasn't required.

      - Found com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Aar' but wasn't required.

      - Found com.android.build.gradle.internal.dependency.VariantAttr 'release' but wasn't required.

      - Found org.gradle.api.attributes.Usage 'java-runtime' but wasn't required.

把gradle配置中的 compile project(':xxx')改成implementation project(':xxx')


5、找不到KeyEventCompat類

v4包升級到了27.0.0,我項目中用它的hasNoModifiers等方法來做的ViewPager的懶加載,找不到KeyEventCompat類,而25.3.1版的v4包中此類是存在的。最後查看源碼,發現這個hasNoModifiers方法已經被KeyEvent實現了。 
貼出解決此處修改的用於實現ViewPager懶加載方法的部分代碼

public boolean executeKeyEvent(KeyEvent event) {
        boolean handled = false;
        if (event.getAction() == KeyEvent.ACTION_DOWN) {
            switch (event.getKeyCode()) {
                case KeyEvent.KEYCODE_DPAD_LEFT:
                    handled = arrowScroll(FOCUS_LEFT);
                    break;
                case KeyEvent.KEYCODE_DPAD_RIGHT:
                    handled = arrowScroll(FOCUS_RIGHT);
                    break;
                case KeyEvent.KEYCODE_TAB:
                    if (Build.VERSION.SDK_INT >= 11) {
//                        if (KeyEventCompat.hasNoModifiers(event)) {
                        if (event.hasNoModifiers()) {
                            handled = arrowScroll(FOCUS_FORWARD);
//                        } else if (KeyEventCompat.hasModifiers(event, KeyEvent.META_SHIFT_ON)) {
                        } else if (event.hasModifiers(KeyEvent.META_SHIFT_ON)) {
                            handled = arrowScroll(FOCUS_BACKWARD);
                        }
                    }
                    break;
            }
        }
        return handled;
    }





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章