《第一行代碼 Android 2版》筆記 二:各類實踐問題總結

這段時間,在學習《第一行代碼 Android 2版》過程中遇到了以下問題,經過各種途徑都已一一解決;在此公佈,僅供參考。

一、打開 Android Studio 卡在「Fetching Android SDK component information」界面。

如圖:

Android Studio First Run 檢測 Android SDK 及更新,由於衆所周知的原因,我們會「Unable to access Android SDK add-on list」,而且大家一般也已經提前配置好了 Android SDK,真正需要更新的時候手動去 SDK Manager 更新就好了。

解決方案:

在 Android Studio 安裝目錄 bin/idea.properties 文件最後追加一句

disable.android.first.run=true

參考: http://ask.android-studio.org/?/article/14

二、新建工程後構建時提示找不到 appcompat-v7

Error:Failed to find: com.android.support:appcompat-v7:22.+

解決方案:

  1. 打開 SDK Manager,然後安裝 Extras 下的 Android Support Repository:

  2. Rebuild 工程。

三、aidl 文件的放置

按以前 Eclipse 的方式,將 aidl 及其包目錄層級放置在與自己的頂級包同級的目錄下,即如下的 android/content/pm:

app/src/main
├─assets
├─java
│  ├─android
│  │  └─content
│  │      └─pm
│  └─org
│      └─mazhuang
│          └─easycleaner
└─res
   ├─drawable
   ├─layout
   ├─menu
   ...

然而這樣在調用處一直報錯:

Cannot resolve symbol 'IPackageStatsObserver'

解決方案:

將 aidl 文件放置在與 app/src/main/java 目錄同級的 app/src/main/aidl 文件夾下。

app/src/main
├─aidl
│  └─android
│      └─content
│          └─pm
├─assets
├─java
│  └─org
│      └─mazhuang
│          └─easycleaner
└─res
   ├─drawable
   ├─layout
   ├─menu
   ...

四、在 Android Studio 裏編譯通過之後,命令行使用 gradlew build 爲什麼還是會重新下載 Gradle?

Gradle 的版本在 Android Studio 工程裏有三處:

1、gradle/wrapper/gradle-wrapper.properties 文件的 distributionUrl 字段裏指定的。

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-all.zip

比如這裏指定的是 2.8 版本。

2、Android Studio 的 File > Project Structure > Project 裏顯示的。

這個實際上就是顯示的「一」裏的版本。

3、Android Studio 的 File > Settings > Build, Execution, Deployment > Build Tools > Gradle 裏選擇的是「Use default gradle wrapper (recommended)」還是「Use local gradle distribution」。

出現題目裏的問題一般是由於「三」中選擇的是「Use local gradle distribution」,這個選項下的「Gradle home」路徑一般是指向 Android Studio 安裝目錄下的 Gradle 目錄,比如 C:/Program Files/Android/Android Studio/gradle/gradle-2.8,而 gradlew 腳本是獨立於 Android Studio 的,所以並不受其配置的影響,它是使用「一」裏指定的版本,會到 ~/.gradle/wrapper/dists 目錄下去尋找對應版本的 Gradle 是否已經存在,如果沒有話就會去重新下載。

五、模擬器啓動失敗

PANIC: ANDROID_SDK_HOME is defined but could not find Nexus_5_API_23.ini file in $ANDROID_SDK_HOME/.android/avd
(Note: avd is searched in the order of $ANDROID_AVD_HOME,$ANDROID_SDK_HOME/.android/avd and $HOME/.android/avd)

實際上文件存在於 $HOME/.android/avd 目錄下,但看樣子如果設置了 $ANDROID_SDK_HOME 環境變量,Android Studio 在 $ANDROID_SDK_HOME/.android/avd 下找不到模擬器文件將直接報錯,而不會再去找 $HOME 目錄下的文件。

解決方案:

添加 $ANDROID_AVD_HOME 環境變量,值爲 $HOME/.android/avd 的展開全路徑。

六、debug.keystore 的存放位置

在使用高德地圖 SDK 時,需要 key 與 keystore 文件的 sha1 校驗通過,而我將 debug.keystore 拷貝到 $HOME/.android 目錄下後發現一直提示 key 校驗失敗,也就是沒有使用我拷貝到 $HOME/.android 目錄下的 debug.keystore 來做 debug 簽名。

原因是 debug.keystore 的默認存儲路徑是 $HOME/.android,但是如果配置了 $ANDROID_SDK_HOME,則會將 debug.keystore $ANDROID_SDK_HOME/.android 目錄下。

解決方案:

將 debug.keystore 文件拷貝到 $ANDROID_SDK_HOME/.android 目錄下。

BTW:

關於給 App 簽名的手動、自動方法參考 Signing Your Applications

Android Studio 自動生成的 debug.keystore 的信息:

  • Keystore password: android
  • Key alias: androiddebugkey
  • Key password: android

七、一直提示 Please configure Android SDK

這是在一次電腦斷電後出現的,試了一些方法,更新 Android Studio,將 SDK Platforms 刪除了重新下,都不行,後來發現 Build Tools 可以更新,更新完後就好了。

More than one file was found with OS independent path

比如,在 netty-buffer-4.1.5.Final.jar 與 netty-common-4.1.5.Final.jar 中都有 META-INF/io.netty.version.properties,所以編譯時報錯:

More than one file was found with OS independent path 'META-INF/io.netty.versions.properties'

解決方案:

在 app/build.gradle 裏添加如下內容:

android {
    packagingOptions {
        pickFirst 'META-INF/*'
    }
}

表示只保留一份該文件。

參考:Android Studio: Duplicate files copied in APK META-INF/DEPENDENCIES when compile

八、打開 uiautomatorviewer 報錯

打開 uiautomatorviewer 報錯,提示:

Unable to connect to adb. Check if adb is installed correctly.

實際 adb 命令是可正常使用的。

解決方法:

打開 uiautomatorviewer.bat 文件(Windows 下,其它系統可能是 .sh),找到下面這行(一般是最後一行):

call "%java_exe%" "-Djava.ext.dirs=%javaextdirs%" "-Dcom.android.uiautomator.bindir=%prog_dir%" -jar %jarpath% %*

將其中的 %prog_dir% 改爲 Android SDK 的 tools 目錄路徑,比如:

call "%java_exe%" "-Djava.ext.dirs=%javaextdirs%" "-Dcom.android.uiautomator.bindir=D:\Android\sdk\tools" -jar %jarpath% %*

參考:In UI automator viewer Error Obtaining Device screenshot, Reason : Error Unable to connect to adb. Check if adb is installed correctly

九、is not translated in “zh”

報錯信息:

Error: "app_name" is not translated in "zh" (Chinese) [MissingTranslation]

在引用了 Umeng 的 SDK 後編譯報錯,疑是 Umeng 包裏的 values-zh 導致。

解決方案 1:

<?xml version="1.0" encoding="utf-8"?>
<resources
  xmlns:tools="http://schemas.android.com/tools"
  tools:ignore="MissingTranslation" >

解決方案 2:

在主項目的 build.gradle 裏添加如下代碼:

android {
    lintOptions {
        checkReleaseBuilds false
        abortOnError false
    }
}

參考:

十、一直卡在 Gradle:Resolve dependencies’app:debugCompile’

這種情況一般是 Gradle 去拉取某個 dependencies 的時候連不上導致。

一種方法是如果本地有能編譯通過的其它工程,修改 compileSdkVersion 和 buildToolsVersion 及 dependencies 裏的版本爲能編譯通過的工程的版本;另一種方法是將對應的依賴包 jar 下載到本地放到 libs 裏面;還有一種思路是修改 jcenter() 爲其它可用的源。

十一、更新到 Android Studio 3.0 後報錯

提示信息:

Unable to resolve dependency for ':internal@packagingOptions/compileClasspath': Could not resolve project :commonlib.

Could not resolve project :commonlib.
Required by:
    project :internal
 > Unable to find a matching configuration of project :commonlib:
     - Configuration 'debugApiElements':
         - Required com.android.build.api.attributes.BuildTypeAttr 'packagingOptions' and found incompatible value 'debug'.
         - Required com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Aar' and found compatible value 'Aar'.
         - Found com.android.build.gradle.internal.dependency.VariantAttr 'debug' but wasn't required.
         - Required org.gradle.api.attributes.Usage 'java-api' and found compatible value 'java-api'.
     - Configuration 'debugRuntimeElements':
         - Required com.android.build.api.attributes.BuildTypeAttr 'packagingOptions' and found incompatible value 'debug'.
         - Required com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Aar' and found compatible value 'Aar'.
         - Found com.android.build.gradle.internal.dependency.VariantAttr 'debug' but wasn't required.
         - Required org.gradle.api.attributes.Usage 'java-api' and found incompatible value 'java-runtime'.
     - Configuration 'releaseApiElements':
         - Required com.android.build.api.attributes.BuildTypeAttr 'packagingOptions' and found incompatible value 'release'.
         - Required com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Aar' and found compatible value 'Aar'.
         - Found com.android.build.gradle.internal.dependency.VariantAttr 'release' but wasn't required.
         - Required org.gradle.api.attributes.Usage 'java-api' and found compatible value 'java-api'.
     - Configuration 'releaseRuntimeElements':
         - Required com.android.build.api.attributes.BuildTypeAttr 'packagingOptions' and found incompatible value 'release'.
         - Required com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Aar' and found compatible value 'Aar'.
         - Found com.android.build.gradle.internal.dependency.VariantAttr 'release' but wasn't required.
         - Required org.gradle.api.attributes.Usage 'java-api' and found incompatible value 'java-runtime'.

情況是有一個叫 internal 的 project 依賴一個叫 commonlib 的 module,最後查到原因如下:

internal project 的 build.gradle 文件裏寫了這麼一段:

android {
    ...
    buildTypes {
        debug {
            signingConfig signingConfigs.release
        }
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.release
        }
        packagingOptions {
            exclude 'META-INF/INDEX.LIST'
            exclude 'log4j.xml'
        }
    }
}

實際 packagingOptions 應該放到 buildTypes 之外,改成這樣就 OK 了:

android {
    ...
    packagingOptions {
        exclude 'META-INF/INDEX.LIST'
        exclude 'log4j.xml'
    }

    buildTypes {
        debug {
            signingConfig signingConfigs.release
        }
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.release
        }
    }
}

以前曾經通過這樣修改臨時掩蓋了問題,讓編譯能過:

dependencies {
    ...
    implementation project(path: ':commonlib', configuration: 'default') // 臨時方案
    // implementation project(':commonlib')  // 原來的樣子
}

這樣修改編譯能通過,但是會有個問題,就是在 internal project 工程裏調用 commonlib 的方法的地方,Ctrl + 鼠標左鍵,或者右鍵 Go To Declaration 時會跳到 ~/.gradle/caches/transforms-1/files-1.1/commonlib-release.aar 目錄裏的 .class 文件,而非 .java 源文件。

回答在 StackOverflow 的一個問題 下。

十二、啓動模擬器提示 Intel HAXM is required to run this AVD your CPU does not support VT-x

我使用 Win10 系統,換主板之後遇到的,之前模擬器是能正常運行的。

我遇到的原因是 Hyper-V 的影響,導致無法安裝 HAXM,雖然在 msconfig 裏查看我的 Hyper-V 服務都已經停止,我在 BIOS 裏也已經 Enable 了 Virtualization Technology 相關的選項,仍然報相同的錯誤。

解決步驟參考 http://blog.csdn.net/WangZuoChuan/article/details/54620016

  1. 打開管理員權限的 CMD

  2. 運行 bcdedit /copy {current} /d “Windows10 no Hyper-V

    這時會輸出一個 UUID

  3. 執行 bcdedit /set {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} hypervisorlaunchtype OFF

    將 XXX 部分換成步驟 2 裏輸出的 UUID

  4. 在 msconfig 的「引導」裏將 Windows 10 no Hyper-V 設爲默認

  5. 重啓

十三、Android Studio 裏對所有 Activity 顯示警告

警告信息:

methods findViewById(int) from android.app.Activity and findViewById(int) from android.support.v7.app.AppCompatActivity are inherited with the same signature

解決方案:

項目裏有幾個模塊,有的 compileSdkVersion 和 targetSdkVersion 是 25,有的是 26,全部改成 26 並把 appcompat-v7 等 dependencies 也改成 26 對應版本後問題消失。(但詭異的是我後來改回 25 想復現一下,問題卻不再出現了)

十四、Plugin with id ‘com.android.application’ not found

導入一個別人做的工程的時候遇到報錯:

Error:(1, 0) Plugin with id 'com.android.application' not found

懷疑是使用比較老的版本的 Android Studio 創建,該工程只有一個 build.gradle 文件——我們平時創建的工程應該是有兩個,一個 Project 級別的,一個 Module 級別的。

它是隻有一個 Project 級別的 gradle 文件,但是內容卻是 Module 級別 gradle 文件的內容。

後來在 StackOverflow 上找到 解決方案

在 build.gradle 文件頂部添加如下代碼(注意 Gradle 版本與 Gradle Plugin 的版本對應):

buildscript {
    repositories {
        jcenter()
        google()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.0'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
        google()
    }
}

十五、升級後 Gradle sync 出錯

從 Android Studio 3.0.1 升級到 3.1 的時候,Check for Updates... 提示超時,於是掛了代理升級。但是升級完成之後,打開以前能順利構建的工程,提示 Cause: jcenter.bintray.com:443 failed to respond,懷疑是代理的原因,於是在 Settings 裏將 HTTP Proxy 選項改爲以前的 no proxy,報錯變成 Connection refused: connect,搜索了一番之後找到 這個,依提示打開 ~/.gradle/gradle.properties,發現裏面果然還存在代理的設置信息,刪除之後重啓 Android Studio,問題解決。

十六、Generate JavaDoc 提示“錯誤: 編碼GBK的不可映射字符”

所有相關文件的編碼都是 UTF-8,在 Android Studio 裏沒有找到設置 JavaDoc 相關的編碼設置項,於是在 Generate JavaDoc 時彈出的 Specify Generate JavaDoc Scope 對話框的 Other command line arguments 一項裏填入 -encoding utf-8 -charset utf-8,問題解決。

android-studio-javadoc

 

十七、升級 Gradle Plugin 版本後報錯

The SourceSet 'instrumentTest' is not recognized by the Android Gradle Plugin. Perhaps you misspelled something?

android { sourceSets { } } 裏的 instrumentTest.setRoot(...) 改爲 androidTest.setRoot(...) 後問題解決。

十八、編譯報錯 Error:Execution failed for task ‘:app:transformClassesWithDexForRelease’

我這裏的原因是一個 APP 依賴一個 Module,這兩個使用了相同的包名,將 APP 的包名改了之後問題解決。

十九、升級到 3.1 後編輯 Gradle 文件卡頓

不止是卡頓……基本上就是整個 Android Studio 卡住幾十秒沒辦法動的那種。在網上搜索之後發現遇到這種問題的網友還挺多,果然是垃圾軟件毀我青春 :-P。

參考 https://blog.csdn.net/wangluotianxi/article/details/79757558,卡頓原因是編輯 Gradle 文件過程中一直在請求下面兩個接口:

http://search.maven.org/solrsearch/select?q=g:%22com.google.android.support%22+AND+a:%22wearable%22&core=gav&rows=1&wt=json
http://search.maven.org/solrsearch/select?q=g:%22com.google.android.gms%22+AND+a:%22play-services%22&core=gav&rows=1&wt=json

而且,結果返回之前會卡住界面,而我們的網絡訪問這倆網址基本只能等到超時返回了,所以,臨時解決方案是在 hosts 文件裏添加如下內容,讓這倆請求快速失敗返回:

127.0.0.1 search.maven.org

暫未發現對正常功能有影響。

二十、編譯報錯 You should manually set the same version via DependencyResolution

Android dependency ‘org.mazhuang:commonlib’ has different version for the compile (0.0.4) and runtime (0.0.5) classpath. You should manually set the same version via DependencyResolution

Project A 使用了 Module B,A 依賴 commonlib(0.0.4),而 Module B 裏引用了 commonlib(0.0.5),將 A 也改爲依賴 commonlib(0.0.5) 即可。

二十一、編譯報錯 Please use JDK 8 or newer

Gradle Sync 的時候無法成功,報錯

Gradle sync failed: Please use JDK 8 or newer

嘗試 Rebuild 報錯

Supplied javaHome is not a valid folder.

原因是我在 Project Settings 的 SDK Location 裏手動指定了 JDK 的版本,但是後來升級了 JDK,所以原有路徑失效了。

解決方法是將 Project Settings 的 SDK Location 裏 JDK 的路徑改爲正確路徑,或者省事起見可以直接勾選 Use embedded JDK 即可。

二十二、編譯報錯 Caused by: java.io.IOException: Cannot run program

提示找不到 NDK 工具鏈裏的 mips64el-linux-android-strip,導致 Caused by: java.io.IOException: error=2

原因是 NDK r17 移除了對 ARMv5(armeabi)、MIPS 和 MIPS64 的支持,所以對應的工具鏈也沒有了。

解決辦法有幾種:

  1. 檢查 Gradle Plugin 的版本,即 project 級別的 build.gralde 文件裏

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

    com.android.tools.build:gradle 的版本改爲 3.1 以上。

  2. 將 NDK 版本退回 16b,或將 16b 以下的對應 mips 工具鏈的文件夾拷貝到 r17 的對應目錄下。

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