屬性資源與Android命名空間

更新: 對於自定義屬性資源,如今不實用http://schemas.android.com/apk/res/<Packge name> 的形式了, 統一用 java

"http://schemas.android.com/apk/res-auto"


Android應用程序將全部的靜態資源都封裝在了APK文件中,並根據這些資源文件名(不包括擴展名)或key屬性的值生成資源ID。這些ID將做爲變量的形式被定義在R類的相應子類中。例如,全部的圖像資源(res/drawable目錄中的資源文件)都會在R.drawable類中生成相應的變量,變量名就是圖像資源的文件名。當使用這些資源時,只要引用R類中相應的變量,系統就會知道上哪去尋找相應的資源。大多數資源的定位很好理解,例如,"@string/hello"引用了字符串資源hello。"@drawable/icon"引用了圖像資源文件(多是icon.png、icon.jpg等圖像)。但有一類資源的引用可能大多數初學者不太注意,這就是屬性資源。android

爲了解釋屬性資源,如今先來看一段<TextView>標籤的定義代碼。spa

<TextView 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content"/>

 

在這段代碼中設置了android:layout_width和android:layout_height屬性,咱們會發現,若是將android:layout_width改爲android:layout_width1,必定是沒法編譯經過的。而若是不加android命名空間,能夠任意設置<TextView>標籤的屬性,只要屬性和屬性值符合XML規範,就能夠編譯經過。例如,下面的<TextView>標籤設置了test屬性後,徹底能夠進行正常編譯。code

<TextView 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        test="value"/>

從這一點能夠判斷,系統對android:layout_width屬性的驗證與XML自己無關。那麼到底與什麼有關呢?orm

實際上,android:layout_width要分開來看,首先看layout_width。系統內部有一個系統級的R.java文件,全部的系統資源生成的ID都在該文件中的R類相關子類中定義。而在這個R類中有一個attr子類,用於定義系統中全部的屬性,也就是XML標籤設置的屬性名,而這個R類的Package就是android。xml

咱們並不須要去關心R類的代碼,由於這個R類是在Android源代碼編譯時自動生成並編譯的,Android源代碼和Android SDK中並無這個R類的源代碼。不過讀者能夠隨便找一個Android工程,選擇Android 4.2開發包(也能夠是其餘版本),很容易就能夠找到R類及其attr子類,如圖8-12黑框中所示。資源

在attr類中有不少咱們已經很熟悉的成員變量,例如,layout_width、layout_height就是attr類中的兩個變量。那麼這個屬性資源有什麼用呢?開發

系統在檢測XML標籤屬性時,若是能夠肯定某一個R類的位置,就會認爲當前XML標籤的屬性名必須與R.attr類中某個變量名一致,不然會認爲該屬性有誤。那麼系統又是如何肯定R類的位置呢?字符串

答案固然是android命名空間了,也就是說android命名空間會直接指定這個內嵌在系統中R類的位置。下面看一下android命名空間的定義。get

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
……> 
……  
</RelativeLayout>

咱們能夠看到,android命名空間的值是一個Url形式的字符串,不過這個Url是有必定規則的。這個Url的通用形式以下:
 

http://schemas.android.com/apk/res/<Package Name>

也就是說這個Url有一個叫"http://schemas.android.com/apk/res/"的前綴,後面跟的內容就是R類的Package名。結合前面android命名空間的定義可知,Package名就是android。而前面已經提到過,系統內嵌的R類的Package就是android。因此經過這個android命名空間,系統就能夠知道R類的全名(Package Name + Class Name),因此就能夠直接定位了 。

儘管android命名空間的值不能修改,不過android命名空間的名稱是能夠修改的,例如,下面的<TextView>標籤的設置是合法的。
 

<RelativeLayout xmlns:mobile="http://schemas.android.com/apk/res/android"     ……>     <TextView     
        mobile:layout_width="wrap_content"     
        mobile:layout_height="wrap_content"/> 
</RelativeLayout>

假設在當前應用程序中R類的Package是www.mobile.com,而且要引用R類中屬性資源,那麼命名空間應該按以下方式設置。
 

<RelativeLayout 
    xmlns:mobile="http://schemas.android.com/apk/res/www.mobile.com" ……>
     ……  
</RelativeLayout>

固然,屬性資源還不單單能限制屬性名,還能夠約束屬性值,

相關文章
相關標籤/搜索