Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 為Android app提供資源

為Android app提供資源

編輯:關於Android編程

您應該始終外部化應用資源,例如圖像和代碼中的字符串,這樣有利於您單獨維護這些資源。 此外,您還應該為特定設備配置提供備用資源,方法是將它們分組到專門命名的資源目錄中。 在運行時,Android 會根據當前配置使用適當的資源。例如,您可能需要根據屏幕尺寸提供不同的 UI 布局,或者根據語言設置提供不同的字符串。

外部化應用資源後,即可使用在項目R類中生成的資源 ID 訪問這些資源。本文介紹如何對 Android 項目中的資源進行分組,以及如何為特定的設備配置提供備用資源。

分組資源類型


您應將各種資源放入項目res/目錄的特定子目錄下。例如,以下是一個簡單項目的文件層次結構:

MyProject/
    src/  
        MyActivity.java  
    res/
        drawable/  
            graphic.png  
        layout/  
            main.xml
            info.xml
        mipmap/  
            icon.png 
        values/  
            strings.xml  

正如您在此示例中所看到的那樣,res/目錄包含所有資源(在子目錄下):一個圖像資源、兩個布局資源、啟動器圖標的mipmap/目錄以及一個字符串資源文件。資源目錄名稱非常重要,將在表 1 中進行介紹。

表 1.項目res/目錄內支持的資源目錄

目錄 資源類型 animator/ 用於定義屬性動畫的 XML 文件。 anim/ 定義漸變動畫的 XML 文件。(屬性動畫也可以保存在此目錄中,但是為了區分這兩種類型,屬性動畫首選animator/目錄。) color/ 用於定義顏色狀態列表的 XML 文件。 drawable/

位圖文件(.png、.9.png、.jpg、.gif)或編譯為以下 Drawable 資源子類型的 XML 文件:

  • 位圖文件
  • 九宮格(可調整大小的位圖)
  • 狀態列表
  • 形狀
  • 動畫 Drawable
  • 其他 Drawable
mipmap/ 適用於不同啟動器圖標密度的 Drawable 文件。 layout/ 用於定義用戶界面布局的 XML 文件。 menu/ 用於定義應用菜單(如選項菜單、上下文菜單或子菜單)的 XML 文件。 raw/

要以原始形式保存的任意文件。要使用原始InputStream打開這些資源,請使用資源 ID(即R.raw.filename)調用Resources.openRawResource()。

但是,如需訪問原始文件名和文件層次結構,則可以考慮將某些資源保存在assets/目錄下(而不是res/raw/)。assets/中的文件沒有資源 ID,因此您只能使用AssetManager讀取這些文件。

values/

包含字符串、整型數和顏色等簡單值的 XML 文件。

其他res/子目錄中的 XML 資源文件是根據 XML 文件名定義單個資源,而目錄中的values/文件可描述多個資源。對於此目錄中的文件,<resources>元素的每個子元素均定義一個資源。例如,<string>元素創建R.string資源,<color>元素創建R.color資源。

由於每個資源均用其自己的 XML 元素定義,因此您可以根據自己的需要命名文件,並將不同的資源類型放在一個文件中。但是,為了清晰起見,您可能需要將獨特的資源類型放在不同的文件中。 例如,對於可在此目錄中創建的資源,下面給出了相應的文件名約定:

  • arrays.xml,用於資源數組(類型化數組)。
  • colors.xml:顏色值。
  • dimens.xml:尺寸值。
  • strings.xml:字符串值。
  • styles.xml:樣式。
xml/ 可以在運行時通過調用Resources.getXML()讀取的任意 XML 文件。各種 XML 配置文件(如可搜索配置)都必須保存在此處。

注意:切勿將資源文件直接保存在res/目錄內,這會導致出現編譯錯誤。

保存在表 1 中定義的子目錄下的資源是“默認”資源。即,這些資源定義應用的默認設計和內容。但是,采用 Android 技術的不同設備類型可能需要不同類型的資源。例如,如果設備的屏幕尺寸大於標准屏幕,則應提供不同的布局資源,以充分利用額外的屏幕空間。 或者,如果設備的語言設置不同,則應提供不同的字符串資源,以轉換用戶界面中的文本。 要為不同的設備配置提供這些不同資源,除了默認資源以外,您還需要提供備用資源。

 

 

提供備用資源


\

圖 1.兩種不同的設備,均使用不同的布局資源。

幾乎每個應用都應提供備用資源以支持特定的設備配置。 例如,對於不同的屏幕密度和語言,您應分別包括備用 Drawable 資源和備用字符串資源。 在運行時,Android 會檢測當前設備配置並為應用加載合適的資源。

為一組資源指定特定於配置的備用資源:

res/中創建一個以 <resources_name>-形式命名的新目錄。
  • 是相應默認資源的目錄名稱(如表 1 中所定義)。
  • 是指定要使用這些資源的各個配置的名稱(如表 2 中所定義)。

    您可以追加多個 <qualifier>。以短劃線將其分隔。

    注意:追加多個限定符時,必須按照表 2 中列出的相同順序放置它們。如果限定符的順序錯誤,則該資源將被忽略。

  • 將相應的備用資源保存在此新目錄下。這些資源文件的名稱必須與默認資源文件完全一樣。

例如,以下是一些默認資源和備用資源:

res/
    drawable/   
        icon.png
        background.png    
    drawable-hdpi/  
        icon.png
        background.png  

hdpi限定符表示該目錄中的資源適用於屏幕密度較高的設備。其中每個 Drawable 目錄中的圖像已針對特定的屏幕密度調整大小,但是文件名完全相同。 這樣一來,用於引用icon.png或background.png圖像的資源 ID 始終相同,但是 Android 會通過將設備配置信息與資源目錄名稱中的限定符進行比較,選擇最符合當前設備的各個資源版本。

Android 支持若干配置限定符,您可以通過使用短劃線分隔每個限定符,向一個目錄名稱添加多個限定符。表 2 按優先順序列出了有效的配置限定符;如果對資源目錄使用多個限定符,則必須按照表中列出的順序將它們添加到目錄名稱。

表 2.配置限定符名稱。

配置 限定符值 描述 MCC 和 MNC 示例:
mcc310
mcc310-mnc004
mcc208-mnc00
等等

移動國家代碼 (MCC),(可選)後跟設備 SIM 卡中的移動網絡代碼 (MNC)。例如,mcc310是指美國的任一運營商,mcc310-mnc004是指美國的 Verizon 公司,mcc208-mnc00是指法國的 Orange 公司。

如果設備使用無線電連接(GSM 手機),則 MCC 和 MNC 值來自 SIM 卡。

也可以單獨使用 MCC(例如,將國家/地區特定的合法資源包括在應用中)。如果只需根據語言指定,則改用“語言和區域”限定符(稍後進行介紹)。 如果決定使用 MCC 和 MNC 限定符,請謹慎執行此操作並測試限定符是否按預期工作。

另請參閱配置字段mcc和mnc,這兩個字段分別表示當前的移動國家代碼和移動網絡代碼。

語言和區域 示例:
en
fr
en-rUS
fr-rFR
fr-rCA
等等

語言通過由兩個字母組成的ISO 639-1語言代碼定義,(可選)後跟兩個字母組成的ISO 3166-1-alpha-2區域碼(前帶小寫字母“r”)。

這些代碼不區分大小寫;r前綴用於區分區域碼。不能單獨指定區域。

如果用戶更改系統設置中的語言,它有可能在應用生命周期中發生改變。

布局方向 ldrtl
ldltr

應用的布局方向。ldrtl是指“布局方向從右到左”。ldltr是指“布局方向從左到右”,這是默認的隱式值。

它適用於布局、圖片或值等任何資源。

例如,若要針對阿拉伯語提供某種特定布局,並針對任何其他“從右到左”語言(如波斯語或希伯來語)提供某種通用布局,則可編碼如下:

res/
    layout/   
        main.xml  (Default layout)
    layout-ar/  
        main.xml  (Specific layout for Arabic)
    layout-ldrtl/  
        main.xml  (Any "right-to-left" language, except
                  for Arabic, because the "ar" language qualifier
                  has a higher precedence.)

注:要為應用啟用從右到左的布局功能,必須將supportsRtl設置為"true",並將targetSdkVersion設置為 17 或更高。

此項為API 級別 17 中新增配置。

smallestWidth swdp

示例:
sw320dp
sw600dp
sw720dp
等等

屏幕的基本尺寸,由可用屏幕區域的最小尺寸指定。 具體來說,設備的 smallestWidth 是屏幕可用高度和寬度的最小尺寸(您也可以將其視為屏幕的“最小可能寬度”)。無論屏幕的當前方向如何,您均可使用此限定符確保應用 UI 的可用寬度至少為<N>dp。

例如,如果布局要求屏幕區域的最小尺寸始終至少為 600dp,則可使用此限定符創建布局資源res/layout-sw600dp/。僅當可用屏幕的最小尺寸至少為 600dp 時,系統才會使用這些資源,而不考慮 600dp 所代表的邊是用戶所認為的高度還是寬度。smallestWidth 是設備的固定屏幕尺寸特性;設備的 smallestWidth 不會隨屏幕方向的變化而改變。

設備的 smallestWidth 將屏幕裝飾元素和系統 UI 考慮在內。例如,如果設備的屏幕上有一些永久性 UI 元素占據沿 smallestWidth 軸的空間,則系統會聲明 smallestWidth 小於實際屏幕尺寸,因為這些屏幕像素不適用於您的 UI。因此,使用的值應該是布局所需要的實際最小尺寸(通常,無論屏幕的當前方向如何,此值都是布局支持的“最小寬度”)。

以下是一些可用於普通屏幕尺寸的值:

  • 320,適用於屏幕配置如下的設備:
    • 240x320 ldpi(QVGA 手機)
    • 320x480 mdpi(手機)
    • 480x800 hdpi(高密度手機)
    • 480,適用於 480x800 mdpi 之類的屏幕(平板電腦/手機)。
    • 600,適用於 600x1024 mdpi 之類的屏幕(7 英寸平板電腦)。
    • 720,適用於 720x1280 mdpi 之類的屏幕(10 英寸平板電腦)。

      應用為多個資源目錄提供不同的 smallestWidth 限定符值時,系統會使用最接近(但未超出)設備 smallestWidth 的值。

      此項為 API 級別 13 中新增配置。

      另請參閱android:requiresSmallestWidthDp屬性和smallestScreenWidthDp配置字段,前者聲明與應用兼容的最小 smallestWidth;後者存放設備的 smallestWidth 值。

可用寬度 wdp

示例:
w720dp
w1024dp
等等

指定資源應該使用的最小可用屏幕寬度,以dp為單位,由值定義。在橫向和縱向之間切換時,為了匹配當前實際寬度,此配置值也會隨之發生變化。

應用為多個資源目錄提供不同的此配置值時,系統會使用最接近(但未超出)設備當前屏幕寬度的值。 此處的值考慮到了屏幕裝飾元素,因此如果設備顯示屏的左邊緣或右邊緣上有一些永久性 UI 元素,考慮到這些 UI 元素,它會使用小於實際屏幕尺寸的寬度值,這樣會減少應用的可用空間。

此項為 API 級別 13 中新增配置。

另請參閱screenWidthDp配置字段,該字段存放當前屏幕寬度。

可用高度 hdp

示例:
h720dp
h1024dp
等等

指定資源應該使用的最小可用屏幕高度,以“dp”為單位,由值定義。 在橫向和縱向之間切換時,為了匹配當前實際高度,此配置值也會隨之發生變化。

應用為多個資源目錄提供不同的此配置值時,系統會使用最接近(但未超出)設備當前屏幕高度的值。 此處的值考慮到了屏幕裝飾元素,因此如果設備顯示屏的上邊緣或下邊緣有一些永久性 UI 元素,考慮到這些 UI 元素,同時為減少應用的可用空間,它會使用小於實際屏幕尺寸的高度值。 非固定的屏幕裝飾元素(例如,全屏時可隱藏的手機狀態欄)並不在考慮范圍內,標題欄或操作欄等窗口裝飾也不在考慮范圍內,因此應用必須准備好處理稍小於其所指定值的空間。

此項為 API 級別 13 中新增配置。

另請參閱screenHeightDp配置字段,該字段存放當前屏幕寬度。

屏幕尺寸 small
normal
large
xlarge
  • small:尺寸類似於低密度 QVGA 屏幕的屏幕。小屏幕的最小布局尺寸約為 320x426 dp 單位。例如,QVGA 低密度屏幕和 VGA 高密度屏幕。
  • normal:尺寸類似於中等密度 HVGA 屏幕的屏幕。標准屏幕的最小布局尺寸約為 320x470 dp 單位。例如,WQVGA 低密度屏幕、HVGA 中等密度屏幕、WVGA 高密度屏幕。
  • large:尺寸類似於中等密度 VGA 屏幕的屏幕。 大屏幕的最小布局尺寸約為 480x640 dp 單位。 例如,VGA 和 WVGA 中等密度屏幕。
  • xlarge:明顯大於傳統中等密度 HVGA 屏幕的屏幕。超大屏幕的最小布局尺寸約為 720x960 dp 單位。在大多數情況下,屏幕超大的設備體積過大,不能放進口袋,最常見的是平板式設備。此項為 API 級別 9 中新增配置。

    注:使用尺寸限定符並不表示資源僅適用於該尺寸的屏幕。 如果沒有為備用資源提供最符合當前設備配置的限定符,則系統可能使用其中最匹配的資源。

    注意:如果所有資源均使用大於當前屏幕的尺寸限定符,則系統會使用這些資源,並且應用在運行時將會崩潰(例如,如果所有布局資源均用xlarge限定符標記,但設備是標准尺寸的屏幕)。

    此項為 API 級別 4 中新增配置。

    另請參閱screenLayout配置字段,該字段表示屏幕是小尺寸、標准尺寸還是大尺寸。

屏幕縱橫比 long
notlong
  • long:寬屏,如 WQVGA、WVGA、FWVGA
  • notlong:非寬屏,如 QVGA、HVGA 和 VGA

    此項為 API 級別 4 中新增配置。

    它完全基於屏幕的縱橫比(寬屏較寬),而與屏幕方向無關。

    另請參閱screenLayout配置字段,該字段指示屏幕是否為寬屏。

屏幕方向 port
land
  • port:設備處於縱向(垂直)
  • land:設備處於橫向(水平)

    如果用戶旋轉屏幕,它有可能在應用生命周期中發生改變。

    另請參閱orientation配置字段,該字段指示當前的設備方向。

UI 模式 car
desk
television
appliancewatch
  • car:設備正在車載手機座上顯示
  • desk:設備正在桌面手機座上顯示
  • television:設備正在電視上顯示,為用戶提供“十英尺”體驗,其 UI 位於遠離用戶的大屏幕上,主要面向方向鍵或其他非指針式交互
  • appliance:設備用作不帶顯示屏的裝置
  • watch:設備配有顯示屏,戴在手腕上

    此項為 API 級別 8 中新增配置,API 13 中新增電視配置,API 20 中新增手表配置。

    如果用戶將設備放入手機座中,它有可能在應用生命周期中發生改變。 可以使用UiModeManager啟用或禁用其中某些模式。

夜間模式 night
notnight
  • night:夜間
  • notnight:白天

    此項為 API 級別 8 中新增配置。

    如果夜間模式停留在自動模式(默認),它有可能在應用生命周期中發生改變。在這種情況下,該模式會根據當天的時間進行調整。 可以使用UiModeManager啟用或禁用此模式。

屏幕像素密度 (dpi) ldpi
mdpi
hdpi
xhdpi
xxhdpi
xxxhdpi
nodpi
tvdpi
  • ldpi:低密度屏幕;約為 120dpi。
  • mdpi:中等密度(傳統 HVGA)屏幕;約為 160dpi。
  • hdpi:高密度屏幕;約為 240dpi。
  • xhdpi:超高密度屏幕;約為 320dpi。API 級別 8 中新增配置
  • xxhdpi:超超高密度屏幕;約為 480dpi。API 級別 16 中新增配置
  • xxxhdpi:超超超高密度屏幕使用(僅限啟動器圖標,請參閱“支持多個屏幕”中的注釋);約為 640dpi。API 級別 18 中新增配置
  • nodpi:它可用於您不希望縮放以匹配設備密度的位圖資源。
  • tvdpi:密度介於 mdpi 和 hdpi 之間的屏幕;約為 213dpi。它並不是“主要”密度組, 主要用於電視,而大多數應用都不需要它。對於大多數應用而言,提供 mdpi 和 hdpi 資源便已足夠,系統將根據需要對其進行縮放。API 級別 13 中引入了此限定符。

    六個主要密度之間的縮放比為 3:4:6:8:12:16(忽略 tvdpi 密度)。因此,9x9 (ldpi) 位圖相當於 12x12 (mdpi)、18x18 (hdpi)、24x24 (xhdpi) 位圖,依此類推。

    如果您認為圖像資源在電視或其他某些設備上呈現的效果不夠好,而想嘗試使用 tvdpi 資源,則縮放比例為 1.33*mdpi。例如,mdpi 屏幕的 100px x 100px 圖像應該相當於 tvdpi 的133px x 133px。

    注:使用密度限定符並不表示資源僅適用於該密度的屏幕。如果沒有為備用資源提供最符合當前設備配置的限定符,則系統可能使用其中最匹配的資源。

觸摸屏類型 notouch
finger
  • notouch:設備沒有觸摸屏。
  • finger:設備有一個專供用戶通過手指直接與其交互的觸摸屏。

    另請參閱touchscreen配置字段,該字段指示設備上的觸摸屏類型。

鍵盤可用性 keysexposed
keyshidden
keyssoft
  • keysexposed:設備具有可用的鍵盤。如果設備啟用了軟鍵盤(不無可能),那麼即使硬鍵盤沒有展示給用戶,哪怕設備沒有硬鍵盤,也可以使用此限定符。如果沒有提供或已經禁用軟鍵盤,則只有在顯示硬鍵盤時才會使用此限定符。
  • keyshidden:設備具有可用的硬鍵盤,但它處於隱藏狀態,且設備沒有啟用軟鍵盤。
  • keyssoft:設備已經啟用軟鍵盤(無論是否可見)。

    如果提供了keysexposed資源,但未提供keyssoft資源,那麼只要系統已經啟用軟鍵盤,就會使用keysexposed資源,而不考慮鍵盤是否可見。

    如果用戶打開硬鍵盤,它有可能在應用生命周期中發生改變。

    另請參閱配置字段hardKeyboardHidden和keyboardHidden,這兩個字段分別指示硬鍵盤的可見性和任何一種鍵盤(包括軟鍵盤)的可見性。

主要文本輸入法 nokeys
qwerty
12key
  • nokeys:設備沒有用於文本輸入的硬按鍵。
  • qwerty:設備具有標准硬鍵盤(無論是否對用戶可見)。
  • 12key:設備具有 12 鍵硬鍵盤(無論是否對用戶可見)。

    另請參閱keyboard配置字段,該字段指示可用的主要文本輸入法。

導航鍵可用性 navexposed
navhidden
  • navexposed:導航鍵可供用戶使用。
  • navhidden:導航鍵不可用(例如,位於密封蓋子後面)。

    如果用戶顯示導航鍵,它有可能在應用生命周期中發生改變。

    另請參閱navigationHidden配置字段,該字段指示導航鍵是否處於隱藏狀態。

主要非觸摸導航方法 nonav
dpad
trackball
wheel
  • nonav:除了使用觸摸屏以外,設備沒有其他導航設施。
  • dpad:設備具有用於導航的方向鍵。
  • trackball:設備具有用於導航的軌跡球。
  • wheel:設備具有用於導航的方向盤(不常見)。

    另請參閱navigation配置字段,該字段指示可用的導航方法類型。

平台版本(API 級別) 示例:
v3
v4
v7
等等

設備支持的 API 級別。例如,v1對應於 API 級別 1(帶有 Android 1.0 或更高版本系統的設備),v4對應於 API 級別 4(帶有 Android 1.6 或更高版本系統的設備)。

注:有些配置限定符是從 Android 1.0 才開始添加,因此並非所有版本的 Android 系統都支持所有限定符。使用新限定符會隱式添加平台版本限定符,因此較舊版本系統的設備必然會忽略它。 例如,使用w600dp限定符會自動包括v13限定符,因為可用寬度限定符是 API 級別 13 中的新增配置。為了避免出現任何問題,請始終包含一組默認資源(一組“不帶限定符”的資源)。

限定符命名規則

以下是一些關於使用配置限定符名稱的規則:

您可以為單組資源指定多個限定符,並使用短劃線分隔。例如,drawable-en-rUS-land適用於橫排美國英語設備。
這些限定符必須遵循表 2中列出的順序。例如:
  • 錯誤:drawable-hdpi-port/
  • 正確:drawable-port-hdpi/
  • 不能嵌套備用資源目錄。例如,您不能擁有res/drawable/drawable-en/。
  • 值不區分大小寫。在處理之前,資源編譯器會將目錄名稱轉換為小寫,以避免不區分大小寫的文件系統出現問題。 名稱中使用的任何大寫字母只是為了便於認讀。
  • 對於每種限定符類型,僅支持一個值。例如,若要對西班牙語和法語使用相同的 Drawable 文件,則您肯定不能擁有名為drawable-rES-rFR/的目錄,而是需要兩個包含相應文件的資源目錄,如drawable-rES/和drawable-rFR/。然而,實際上您無需將相同的文件都復制到這兩個位置。相反,您可以創建指向資源的別名。

將備用資源保存到以這些限定符命名的目錄中之後,Android 會根據當前設備配置在應用中自動應用這些資源。 每次請求資源時,Android 都會檢查備用資源目錄是否包含所請求的資源文件,然後找到最匹配資源(下文進行介紹)。 如果沒有與特定設備配置匹配的備用資源,則 Android 會使用相應的默認資源(一組用於不含配置限定符的特定資源類型的資源)。

創建別名資源

如果您想將某一資源用於多種設備配置(但是不想作為默認資源提供),則無需將同一資源放入多個備用資源目錄中。 相反,您可以(在某些情況下)創建備用資源,充當保存在默認資源目錄下的資源的別名。

注:並非所有資源都會提供相應機制讓您創建指向其他資源的別名。 特別是,xml/目錄中的動畫資源、菜單資源、原始資源以及其他未指定資源均不提供此功能。

例如,假設您有一個應用圖標icon.png,並且需要不同區域設置的獨特版本。 但是,加拿大英語和加拿大法語這兩種區域設置需要使用同一版本。 您可能會認為需要將相同的圖像復制到加拿大英語和加拿大法語對應的資源目錄中,但事實並非如此。 相反,您可以將用於二者的圖像另存為icon_ca.png(除icon.png以外的任何名稱),並將其放入默認res/drawable/目錄中。然後,在res/drawable-en-rCA/和res/drawable-fr-rCA/中創建icon.xml文件,使用<bitmap>元素引用icon_ca.png資源。這樣,您只需存儲 PNG 文件的一個版本和兩個指向該版本的小型 XML 文件。(XML 文件示例如下。)

Drawable

要創建指向現有 Drawable 的別名,請使用<bitmap>元素。例如:


如果將此文件另存為icon.xml(例如,在備用資源目錄中,另存為res/drawable-en-rCA/),則會編譯到可作為R.drawable.icon引用的資源中,但實際上它是R.drawable.icon_ca資源(保存在res/drawable/中)的別名。

布局

要創建指向現有布局的別名,請使用包裝在<merge>中的<include>元素。例如:



  

如果將此文件另存為main.xml,則會編譯到可作為R.layout.main引用的資源中,但實際上它是R.layout.main_ltr資源的別名。

字符串和其他簡單值

要創建指向現有字符串的別名,只需將所需字符串的資源 ID 用作新字符串的值即可。例如:



  Hello
  @string/hello

R.string.hi資源現在是R.string.hello的別名。

其他簡單值的原理相同。 例如,顏色:



  #f00
  @color/red

 

 

利用資源提供最佳設備兼容性


要使應用支持多種設備配置,則務必為應用使用的每種資源類型提供默認資源,這一點非常重要。

例如,如果應用支持多種語言,請始終包含不帶語言和區域限定符的values/目錄(用於保存字符串)。相反,如果您將所有字符串放入帶有語言和區域限定符的目錄中,則在語言設置不支持您的字符串的設備上運行應用時,應用將會崩潰。 但是,只要提供默認values/資源,應用就會正常運行(即使用戶不理解該語言,這也總比崩潰要好)。

同樣,如果您根據屏幕方向提供不同的布局資源,則應選擇一個方向作為默認方向。 例如,不要在layout-land/和layout-port/中分別提供橫向和縱向的布局資源,而是保留其中之一作為默認設置,例如:layout/用於橫向,layout-port/用於縱向。

提供默認資源至關重要,這不僅僅因為應用可能在超出預期的配置上運行,也因為新版 Android 有時會添加舊版本不支持的配置限定符。若要使用新的資源限定符,又希望維持對舊版 Android 的代碼兼容性,則當舊版 Android 運行應用時,如果不提供默認資源,應用將會崩潰,這是因為它無法使用以新限定符命名的資源。例如,如果將minSdkVersion設置為 4,並使用夜間模式(night或notnight,API 級別 8 中新增配置)限定所有 Drawable 資源,則 API 級別 4 設備無法訪問 Drawable 資源,而且會崩潰。在這種情況下,您可能希望notnight成為默認資源,為此,您應排除該限定符,使 Drawable 資源位於drawable/或drawable-night/中。

因此,為了提供最佳設備兼容性,請始終為應用正確運行所必需的資源提供默認資源。 然後,使用配置限定符為特定的設備配置創建備用資源。

這條規則有一個例外:如果應用的minSdkVersion為 4 或更高,則在提供帶屏幕密度限定符的備用 Drawable 資源時,不需要默認 Drawable 資源。 即使沒有默認 Drawable 資源,Android 也可以從備用屏幕密度中找到最佳匹配項並根據需要縮放位圖。 但是,為了在所有類型的設備上提供最佳體驗,您應該為所有三種類型的密度提供備用 Drawable。

 

 

Android 如何找到最匹配資源


當您請求要為其提供備用資源的資源時,Android 會根據當前的設備配置選擇要在運行時使用的備用資源。為演示 Android 如何選擇備用資源,假設以下 Drawable 目錄分別包含相同圖像的不同版本:

drawable/
drawable-en/
drawable-fr-rCA/
drawable-en-port/
drawable-en-notouch-12key/
drawable-port-ldpi/
drawable-port-notouch-12key/

同時,假設設備配置如下:

區域設置 =en-GB
屏幕方向 =port
屏幕像素密度 =hdpi
觸摸屏類型 =notouch
主要文本輸入法 =12key

通過將設備配置與可用的備用資源進行比較,Android 從drawable-en-port中選擇 Drawable。

系統使用以下邏輯決定要使用的資源:

\

圖 2.Android 如何找到最匹配資源的流程圖。

淘汰與設備配置沖突的資源文件。

drawable-fr-rCA/目錄與en-GB區域設置沖突,因而被淘汰。

drawable/
drawable-en/
drawable-fr-rCA/
drawable-en-port/
drawable-en-notouch-12key/
drawable-port-ldpi/
drawable-port-notouch-12key/

例外:屏幕像素密度是唯一一個未因沖突而被淘汰的限定符。 盡管設備的屏幕密度為 hdpi,但是drawable-port-ldpi/未被淘汰,因為此時每個屏幕密度均視為匹配。

  1. 選擇列表(表 2)中(下一個)優先級最高的限定符。(先從 MCC 開始,然後下移。)
  2. 是否有資源目錄包括此限定符?
  • 若無,請返回到第 2 步,看看下一個限定符。(在該示例中,除非達到語言限定符,否則答案始終為“否”。)
  • 若有,請繼續執行第 4 步。
  • 淘汰不含此限定符的資源目錄。在該示例中,系統會淘汰所有不含語言限定符的目錄。
drawable/
drawable-en/
drawable-en-port/
drawable-en-notouch-12key/
drawable-port-ldpi/
drawable-port-notouch-12key/

例外:如果涉及的限定符是屏幕像素密度,則 Android 會選擇最接近設備屏幕密度的選項。通常,Android 傾向於縮小大型原始圖像,而不是放大小型原始圖像。

返回並重復第 2 步、第 3 步和第 4 步,直到只剩下一個目錄為止。在此示例中,屏幕方向是下一個判斷是否匹配的限定符。因此,未指定屏幕方向的資源被淘汰:
drawable-en/
drawable-en-port/
drawable-en-notouch-12key/

剩下的目錄是drawable-en-port。

盡管對所請求的每個資源均執行此程序,但是系統仍會對某些方面做進一步優化。 例如,系統一旦知道設備配置,即會淘汰可能永遠無法匹配的備用資源。 比如說,如果配置語言是英語(“en”),則系統絕不會將語言限定符設置為非英語的任何資源目錄包含在選中的資源池中(不過,仍會將不帶語言限定符的資源目錄包含在該池中)。

根據屏幕尺寸限定符選擇資源時,如果沒有更好的匹配資源,則系統將使用專為小於當前屏幕的屏幕而設計的資源(例如,如有必要,大尺寸屏幕將使用標准尺寸的屏幕資源)。 但是,如果唯一可用的資源大於當前屏幕,則系統不會使用這些資源,並且如果沒有其他資源與設備配置匹配,應用將會崩潰(例如,如果所有布局資源均用xlarge限定符標記,但設備是標准尺寸的屏幕)。

注:限定符的優先順序(表 2中)比與設備完全匹配的限定符數量更加重要。例如,在上面的第 4 步中,列表剩下的最後選項包括三個與設備完全匹配的限定符(方向、觸摸屏類型和輸入法),而drawable-en只有一個匹配參數(語言)。但是,語言的優先順序高於其他兩個限定符,因此drawable-port-notouch-12key被淘汰。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved