Android探索之旅(第三十三篇)手把手教你跨過學習Android Studio 3.0的坑

過完了快樂的國慶,也該安安心心的投入工作中了。再次趁工作項目不是太趕急,因此閒的蛋疼索性更新AndroidStudio3.0 Update的一下,再次碰到了一些坑,並作以記錄
本文大部分出來簡書 ThinkNuo &簡書 JonathanHsia

1. gradle 和 buildToolsVersion 版本

Android Studio 3.0 要求 gradle 版本爲 4.1 ,對應的 buildToolsVersion 爲 26.0.2 ,然後記得在項目最外層的 build.gradle 添加 google() ,如果不添加將會導致某些官方依賴下載不了。

buildscript {
    repositories {
        ...
        google()
    }
}

2. module 依賴方式變更

原先依賴 module 使用的是 compile ,現在需要替換爲 api 或 implementation。
api : module 編譯時可用,module 的使用者編譯和運行時可用,這個和過時的 compile 一樣的。
implementation : module 編譯時可用,module 的使用者運行時可用,對於大量使用 library 的項目,可以顯著提高編譯時間,因爲它可以減少構建系統重新編譯一些 module 。
那麼什麼時候用 api ,什麼時候用 implementation 呢?由於公司項目採用的是組件化開發,有個 common module 需要被各個組件依賴,一開始採用的是 implementation ,結果發現會導致別的組件無法引用 common 中的庫( common -> A module ,A module 無法引用 common 依賴的庫 )。
試驗過後得出結論,當這個 module 會被多次引用應該使用 api,不會被別的 module 引用使用 implementation 。
發一下我現在使用的方式

dependencies {
    api fileTree(include: ['*.jar'], dir: 'libs')
    api 'com.squareup.okhttp3:okhttp:3.4.2'
    ...
    debugApi 'com.squareup.leakcanary:leakcanary-android:1.5.1'
    releaseApi 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1'
}

3. apt 插件更換

apt 插件已被廢棄,需更換爲 annotationProcessor 。

//apply plugin: 'android-apt'

dependencies {
    ...
    annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1'
}

4.第三方庫不兼容問題

· retrolambda
Android Studio 3.0 已經支持 Java 8 了,不需要第三方庫來支持,因此需要去掉 retrolambda 庫。
項目最外層的 build.gradle

buildscript {
    ...
    dependencies {
        ...
        //classpath 'me.tatarka:gradle-retrolambda:3.2.5'
    }
}

module 中的 build.gradle

//apply plugin: 'me.tatarka.retrolambda'

android {
    ...
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {
    ...
    //retrolambdaConfig 'net.orfjackal.retrolambda:retrolambda:2.3.0'
}

· butterknife
butterknife 最新版本爲 8.8.0,與 Android Studio 3.0 不兼容,會提示

Caused by: java.lang.NoSuchMethodError: com.android.build.gradle.tasks.ProcessAndroidResources.getPackageForR()Ljava/lang/String;

官方 issue 已經有人提過這個問題,貌似是 gradle 的問題。解決辦法:版本降級到 8.5.1 即可解決。
· 項目中同一個第三庫有多個版本導致編譯失敗
不知道是不是 Android Studio 3.0 編譯現在比以前嚴格了,以前有的庫沒有統一過版本,現在直接編譯不過了。解決辦法:統一第三方庫的版本。
在 Terminal 中輸入 gradle app:dependencies (gradle環境配置可以百度)

...
+--- com.meituan.android.walle:library:1.1.5
|    +--- com.android.support:support-annotations:24.1.1 -> 25.2.0
|    \--- com.meituan.android.walle:payload_reader:1.1.5
...

如果出現了 com.android.support:support-annotations:24.1.1 -> 25.2.0 代表該庫中有自己依賴的庫被升級了,需要去除這個依賴。

dependencies {
    ...
    api('com.meituan.android.walle:library:1.1.5') {
        exclude(group: 'com.android.support', module: 'support-annotations')
    }
}

group 是 : 前面的包名,: 後面的是 module 名字。
如果依賴的是 jar 包,寫法爲 exclude(module: ‘libs/xxx.jar’)。
exclude(group: ‘com.android.support’) 是忽略所有 com.android.support 的module。

4.一直卡在Refreshing項目

第一條中的問題解決後,我出現了

這裏寫圖片描述
這種提示,在正常的流程中,如果不出現第一個問題,會首先出現這個提示,意思是升級現在項目的編譯插件,相信之前升級過AS版本的同學在第一次運行新版本的時候見過這個提示,直接點擊update按鈕就行了.如果不想接着踩坑那麼點擊Dont’t reminmd me againg for this project按鈕就可以了,它代表你還是用之前版本的插件來運行當前項目,也就不會出現後面一大串的問題;

這裏直接點擊update按鈕;
點擊之後如果你網絡不暢通的話就會一直的
loading.......
之所以會這樣,是因爲
點擊該按鈕後實際上做了兩件事情

  • 在主項目的build.gradle文件中的dependencies節點中更改了
``` gradle
 //原先的插件版本
 classpath 'com.android.tools.build:gradle:2.3.3'
 //更改後的插件版本
 classpath 'com.android.tools.build:gradle:3.0.0'
  • 在項目目錄中的gradle > gradle-wrapper.properties文件中的distributionUrl字段更改了
``` 
 //原先的插件版本
 distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
 //更改後的插件版本
 distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip

讀者需要理會其中的用意就可以了
這兩個文件修改後AS就會去下載https://services.gradle.org/distributions/gradle-4.1-all.zip這個文件,不用點什麼奇技淫巧,就等AS下載完吧(基本完不了)

這裏給出兩種解決方案:
兩種解決方案的前提條件是先把該文件下載下來,AS下載的奇慢,那麼把https://services.gradle.org/distributions/gradle-4.1-all.zip扔到迅雷中,分分鐘下載完成(迅雷功能不止於此~);

把文件放到本地的Tomcat服務器,或者IIS服務器中,或者免費的七牛雲服務中,獲取這個文件的下載地址,修改 gradle-wrapper.properties文件中distributionUrl的值爲你的下載地址,關閉AS,重新打開(親測可行);

找到.gradle文件夾路徑:windows一般在 C:\Users<當前登錄用戶名>.gradle,
mac是在:用戶/(當前用戶目錄)/.gradle,解壓下載好的文件到該目錄中,關閉AS,重新打開(未親測);

5.修改輸出apk的文件名導致的異常

第二條問題解決後,出現了
輸出apk異常

Cannot set the value of read-only property 'outputFile' for ApkVariantOutputImpl_Decorated{apkData=Main{type=MAIN, fullName=tiger8shopDebug, filters=[]}} of type com.android.build.gradle.internal.api.ApkVariantOutputImpl. Open File

點擊Open File定位到應用級別的build.gradle文件中的這個位置

static def releaseTime() {
    return new Date().format("yyyy-MM-dd-HH-mm", TimeZone.getDefault())//包含時分秒
}

static def debugTime() {
//    return new Date().format("yyyy-MM-dd", TimeZone.getDefault())
    return new Date().format("yyyy", TimeZone.getDefault())
}

//=============================上面的代碼定義在android節點外,AS3.0版本如果需要輸出apk文件名帶上時間,上面代碼你可以參考下===================================

  //文件輸出名增加版本號和時間
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            def outputFile = output.outputFile
            if (outputFile != null && outputFile.name.endsWith('.apk')) {
                def fileName
                if (outputFile.name.contains("debug")) {//debug版本,使用自己的文件名,方便記憶
                    fileName = "$applicationId _v${defaultConfig.versionName}_${debugTime()}_code${defaultConfig.versionCode}_debug.apk"
                    output.outputFile = new File(outputFile.parent, fileName)//Open File後定位到這個位置,這個配置,識別不出outputFile是啥了
                } else {
                    fileName = "$applicationId _v${defaultConfig.versionName}_code${defaultConfig.versionCode}_${releaseTime()}_${variant.productFlavors[0].name}_release.apk"
                    output.outputFile = new File(outputFile.parent, fileName)
                }
            }
        }
    }

這個是自己之前配置的可以控制AS輸出的apk文件的名稱,新版本不能這樣配置了,看官方的引導可以改成

//AS3.0版本
    android.applicationVariants.all { variant ->
        variant.outputs.all {
            if (variant.name.endsWith("Debug")) {
                //debug包
                outputFileName = "$applicationId _v${defaultConfig.versionName}_${debugTime()}_code${defaultConfig.versionCode}_debug.apk"
            } else {
                //release包
        outputFileName = "$applicationId _v${defaultConfig.versionName}_code${defaultConfig.versionCode}_${releaseTime()}_release.apk"
            }
        }
    }

效果和之前差不多,直接更改,問題KO

6.當然有坑但是也有驚喜,Google 發佈最快的 Android 模擬器,一秒快速啓動!

過去我們在使用AndroidStudio中自帶的模擬器啓動比較慢,體驗不是太好,逼不得已我們去下載其他第三方的模擬器,隨着AndroidStudio3.0強勢來襲,相信不會讓大家失望
效果圖轉載自@亦楓

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