天天看點

Android工程編譯時"No resource found"錯誤-附相關拓展知識一、問題處理二、AAR包三、local.properties

一、問題處理

剛剛在公司編譯的時候突然報錯,其實昨天還是好好的,具體報錯log如下

/Users/dongboqi/android_2/build_tmp_cache/dcdfa5e69b328d9c932f8e56db2f3b8b2ec4271a/output/res/layout/pay_ad_layout.xml
Error:(30, 32) No resource found that matches the given name (at 'textColor' with value '@color/color_2bbb38').
Error:(39, 32) No resource found that matches the given name (at 'svgPaintColor' with value '@color/color_2bbb38').
Error:(67, 32) No resource found that matches the given name (at 'textColor' with value '@color/color_ebebeb').
/Users/dongboqi/android_2/build_tmp_cache/dcdfa5e69b328d9c932f8e56db2f3b8b2ec4271a/output/res/layout/pay_auth_bank_list_item_layout.xml
Error:(51, 28) No resource found that matches the given name (at 'svgPaintColor' with value '@color/color_099fde').
/Users/dongboqi/android_2/build_tmp_cache/dcdfa5e69b328d9c932f8e56db2f3b8b2ec4271a/output/res/layout/pay_card_input_layout.xml
Error:(187, 20) No resource found that matches the given name (at 'style' with value '@style/pay_text_12_000000').
..............
           

不太清除具體發生的原因,一開始猜測是本地資源誤删除,于是從Git上面拉取了最新的版本,但是依然有這個問題,最後問了一下leader,發現了問題所在:

1. 首先這些找不到資源的都是編譯之後的(也就是遠端拉取的AAR包),也就是說這些包中出現了問題很大機率不是本地的問題,而是遠端别人的包出了問題(這裡看了檔案大概清楚是支付部門那邊出了問題)

2. 既然遠端出了問題,那麼我們隻能自己編譯本地的包來替代遠端的(我們一般都不會編譯所有的包,太龐大了,隻把我們可能修改的子產品進行編譯,其他的都是遠端使用編譯好的包的),這裡我們就在local.properties裡面的sourceProject裡面添加本地的支付子產品的包就可以變異了

下面補充幾個不太了解的知識點:

二、AAR包

AAR包:AAR(Android Archive)包是一個Android庫項目的二進制歸檔檔案。包含所有資源,class以及res資源檔案全部包含。如果你隻是一個簡單的類庫那麼使用生成的*.jar檔案即可;如果你的是一個UI庫,包含一些自己寫的控件布局檔案以及字型等資源檔案那麼就隻能使用*.aar檔案。

我們随便找一個aar檔案,然後修改字尾名為‘zip’或者‘rar’格式,然後解壓該檔案,打開解壓後的檔案夾,截圖如下所示:(每個aar解壓後的内容可能不完全一樣,但是都會包含AndroidManifest.xml,classes.jar,res,R.txt)

Android工程編譯時"No resource found"錯誤-附相關拓展知識一、問題處理二、AAR包三、local.properties

*.aar檔案使用有兩種方式,一種是使用線上的(網上的),一種是添加本地的*.aar檔案。網絡加載,隻要你知道*.aar檔案在maven中的路徑即可,此處不示範了。下面主要看看在Android Studio中如何加載本地的*.aar檔案。

(1).把aar檔案放在一個檔案目錄内,比如就放在libs目錄内;

(2).在app的build.gradle檔案添加如下内容;

repositories {
    flatDir {
        dirs 'libs' 
    }
}
           

(3).之後隻需要添加一句gradle依賴便友善的引用了該aar檔案;

dependencies {
   ...
    compile(name:'test', ext:'aar')
   ...
}
           

至此,在Android Studio中加載本地的*.aar檔案就結束,是不是很簡單呢!需要補充一點,如果*.aar檔案中引用了其他Maven 倉庫的包,那麼需要在gradle中添加依賴,否則在運作的時候,可能會報“Caused by: Java.lang.ClassNotFoundException”!

三、local.properties

我唯一用到的這個檔案的時候就是确定應該本地編譯項目的哪些子產品(檔案夾),這些再擴充一下相關的隻是把。

通過Android Studio建立一個Android工程後,在工程的根目錄中都會生成一個名稱為:

local.properties

檔案,該檔案一般用來 存放該Android工程私有的屬性配置,比如Android的sdk路徑等等。local.properties檔案一般都是存儲到本地,禁止送出到伺服器上。 這裡我們直接看官方注釋 ## This file is automatically generated by Android Studio.

# Do not modify this file -- YOUR CHANGES WILL BE ERASED!

#

# This file must *NOT* be checked into Version Control Systems,

# as it contains information specific to your local configuration.

#

# Location of the SDK. This is only used by Gradle.

# For customization when using a Version Control System, please read the

# header note.

最基本的就是存放本機的SDK和NDK的位址了,如下所示

ndk.dir=D\:\\soft\\android-ndk-r10e
sdk.dir=D\:\\soft\\SDKandroidStudio
           

當然你也可以存放你自己定義的一些資訊(公司通過local.Properties配置編譯哪些子產品應該就是通過下面的過程)

比如下面配置簽名檔案

key.file=C\:\\work\\Key.jks
keyAlias=key
keyPassword=key7766
storePassword=key6677
           

最重要的是需要在gradle裡面讀取這些資訊,下面的示例,但是原理應該是類似的

signingConfigs {
        config {
            
            //加載資源
            Properties properties = new Properties()
            InputStream inputStream = project.rootProject.file('local.properties').newDataInputStream() ;
            properties.load( inputStream )

            //讀取檔案
            def sdkDir = properties.getProperty('key.file')
            storeFile file( sdkDir )

            //讀取字段
            def key_keyAlias = properties.getProperty( 'keyAlias' )
            def key_keyPassword = properties.getProperty( 'keyPassword' ) ;
            def key_storePassword = properties.getProperty( 'storePassword' ) ;

            storePassword key_storePassword
            keyAlias key_keyAlias
            keyPassword key_keyPassword
        }
    }
           

還有一些别人的使用建議:

* local.properties 裡面存放的是各插件需要的本機相關的資訊, 例如Android gradle插件可能需要 SDK路徑, NDK路徑, 别的插件需要的可能就是其他配置資訊.

* local.properties 存放敏感資料, 例如某些插件需要 使用者名, 密碼, api_key 等, 與隐私相關的資料.

例如: 在插件開發的時候, 你需要将工程打包後, publish 到遠端倉庫的時候, 需要 帳号, 密碼, 此時, 帳号, 密碼, 一般就是存放在 local.properties 裡面