android裏面,資源文件和資源ID之間的映射是如何工做的?
問題描述:
作Android應用開發的時候,咱們知道能夠經過 R.id.xxx 來很是方便的訪問應用程序的資源。
可是任何資源最終要編譯成二進制格式的,那麼在這種機制下,系統是如何工做的?
例如,在layout1.xml裏面,咱們這樣寫:
<Button android:id="@+id/button1" >
而後AAPT 會生成R.java文件:
public static final int button1=0x7f05000b;
接下來在生成*.apk的時候,像 @+id/button1 這樣的ID會用」0x7f05000b」這樣的數字代替
因此,咱們在調用
findViewById(R.id.button1);
的時候,實際上調用的是像」0x7f05000b」這樣的資源ID。那麼這中間到底發生了什麼呢?例如系統是如何把一個圖片和數字ID對應起來的呢?
回答:
在編譯的時候,AAPT會掃描你所定義的全部資源(在不一樣文件中定義的以及單獨的資源文件),而後給它們指定不一樣的資源ID。
資源ID 是一個32bit的數字,格式是PPTTNNNN , PP表明資源所屬的包(package) ,TT表明資源的類型(type),NNNN表明這個類型下面的資源的名稱。 對於應用程序的資源來講,PP的取值是0×7f。
TT 和NNNN 的取值是由AAPT工具隨意指定的–基本上每一種新的資源類型的數字都是從上一個數字累加的(從1開始);而每個新的資源條目也是從數字1開始向上累加的。
因此若是咱們的這幾個資源文件按照下面的順序排列,AAPT會依次處理:
<code>layout/main.xml </code>
<code>drawable/icon.xml </code>
<code>layout/listitem.xml</code>
按照順序,第一個資源的類型是」layout」 因此指定TT==1, 這個類型下面的第一個資源是」main」 ,因此指定NNNN==1 ,最後這個資源就是0x7f010001。
第二個資源類型是」drawable」,因此指定TT==2,這個類型下的」icon」 指定NNNN ==1,因此最終的資源ID 是 0x7f020001。
第三個資源類型是」layout」,而這個資源類型在前面已經有定義了,因此TT仍然是1,可是」listitem」這個名字是新出現的,因此指定NNNN==2,所以最終的資源ID 就是 0x7f010002。
注意的是,AAPT在每一次編譯的時候不會去保存上一次生成的資源ID標示,每當/res目錄發生變化的時候,AAPT可能會去從新給資源指定ID號,而後從新生成一個R.java文件。所以,在作開發的時候,你不該該在程序中將資源ID持久化保存到文件或者數據庫。而資源ID在每一次編譯後都有可能變化。
一旦資源被編譯成二進制文件的時候,AAPT會生成R.java 文件和「resources.arsc」文件,「R.java」用於代碼的編譯,而」resources.arsc」則包含了所有的資源名稱、資源ID和資源的內容(對於單獨文件類型的資源,這個內容表明的是這個文件在其.apk 文件中的路徑信息)。這樣就把運行環境中的資源ID 和具體的資源對應起來了。
在調試的時候,你可使用「 aapt dump resources <apk的路徑>」來看到對resources.arsc文件的詳細描述信息。
關於二進制資源表的詳細定義在 resources數據結構的定義頭文件裏面:
http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob;f=include/utils/ResourceTypes.h
關於設備上使用的二進制資源的具體實如今這裏:
http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob;f=libs/utils/ResourceTypes.cpp
原文連接:http://tweetyf.org/2013/02/mapping_between_res_resid_android.htmlhtml