屬性資源與Android命名空間

來源:互聯網
上載者:User

標籤:

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

"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等映像)。但有一類資源的引用可能大多數初學者不太注意,這就是屬性資源。

為瞭解釋屬性資源,現在先來看一段<TextView>標籤的定義代碼。

<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屬性後,完全可以進行正常編譯。

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

從這一點可以判斷,系統對android:layout_width屬性的驗證與XML本身無關。那麼到底與什麼有關呢?

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

我們並不需要去關心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命名空間的定義。

<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>

當然,屬性資源還不僅僅能限制屬性名稱,還可以約束屬性值,

屬性資源與Android命名空間

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.