當我們將一些提供了不同的資源文件可供Android系統選擇的時候,Android會在運行時會根據一套適配的規則選擇最符合當前配置的資源。為了說明Android怎么選擇資源,假設我們有以下可選的資源文件目錄,每一個目錄都包含同一張圖片的不同版本。
drawable/
drawable-en/
drawable-fr-rCA/
drawable-en-port/
drawable-en-notouch-12key/
drawable-port-ldpi/
drawable-port-notouch-12key/
假設系統配置是下面這樣的:
Locale = en-GB
Screen orientation = port
Screen pixel density = hdpi
Touchscreen type = notouch
Primary text input method = 12key
在將系統配置與可選的資源對比之后,Android選擇drawable-en-port/
Android根據下面的邏輯去選擇資源
1、排除跟系統配置不同的資源文件
drawable-fr-rCA/被排除了,因為它違背了Locale=en-GB。
drawable/
drawable-en/
drawable-fr-rCA/
drawable-en-port/
drawable-en-notouch-12key/
drawable-port-ldpi/
drawable-port-notouch-12key/
例外:屏幕像素密度(Screen pixel density) 這種限定詞不會簡單地因為跟當前系統配置不同而被排除。即使當前屏幕的配置是hdpi,drawable-port-ldpi/不會被排除,因為每種屏幕密度都被認為可適配的。更多相關的信息查看Supporting Multiple Screens.
2、選出列表中(下一個)最高優先級限定詞(開始于MCC,然后越往下越低)。
3、是否還有包含這個限定詞的資源目錄?
●否,返回步驟2然后查找下一個限定詞(在例子中,答案是否,直到語言限定詞被找到)。
●是,繼續第4步。
4、排除沒有包含這個限定詞的資源文件目錄。在這個例子中,系統排除了所有沒有包含語言限定詞的目錄:
drawable/
drawable-en/
drawable-en-port/
drawable-en-notouch-12key/
drawable-port-ldpi/
drawable-port-notouch-12key/
例外:如果限定詞是屏幕像素密度(device screen density),Android會選擇最接近屏幕像素密度的一個。 總之,Android比較偏向于將原始的大圖片縮放成 小的圖片。 參考 Supporting Multiple Screens.
5、返回重復步驟2,3,和4知道只剩下一個目錄。在這個例子中,屏幕方向是下一個用來匹配資源的限定詞。所以,沒有限定屏幕方向的資源文件目錄就被排除了。
drawable-en/
drawable-en-port/
drawable-en-notouch-12key/
最后剩下的目錄是drawable-en-port
雖然在請求每一個資源文件的時候都會執行上述的處理過程,但是系統自己會進行查找過程的優化。其中一個優化就是一旦系統的配置已經被加載,它可能會排除掉永遠不會匹配的可選資源。比如,如果配置中的語言為英語(“en"),那么任何其他有語言限定詞又不是英語的就會從可選的資源目錄池當中排除(但是如果資源目錄中沒有語言限定詞,那么它依然是可選的)。
當根據屏幕大小選擇資源的時候,如果找不到能跟當前屏幕匹配的資源,為比當前更小的屏幕設計的資源就會被使用(比如,一個large-size屏幕將會在必要的時候使用normal-size屏幕的資源文件)。然而,如果唯一可選的資源比當前的屏幕大,系統不會使用它們并且你的程序會崩潰如果沒有其他的資源能夠跟系統配置匹配(比如,所有的layout資源都有xlarge的限定,但是當前的設備屏幕是normal-size的)。
注意:在準確匹配資源上,限定詞的優先級(在表2)比限定詞的數量更重要。例如,在上面的步驟4,列表中的最后一項還包含了三種能夠準確匹配系統配置的資源(orientation、touchscreen type和input method),然而drawable-en那項只有一項匹配(語言)。然而,語言有比其他限定詞更高的優先級,所以drawable-port-notouch-12key就被排除了。
本文翻譯自How Android Finds the Best-matching Resource
文章列表