應(yīng)用資源是指應(yīng)用中與源代碼分離的資源永毅,如圖像、音頻文件以及任何與應(yīng)用的視覺呈現(xiàn)有關(guān)的內(nèi)容人弓。在Android項目中的每一項資源沼死,SDK構(gòu)建工具都會定義一個唯一的整形ID,可以通過ID對資源進行應(yīng)用票从。提供與源代碼分離的資源的其中一個最重要優(yōu)點在于漫雕,您可以提供針對不同設(shè)備配置的備用資源滨嘱。
1、應(yīng)用資源分組
項目res/目錄下支持的資源目錄
目錄 | 資源類型 |
---|---|
animator/ | 定義屬性動畫的xml文件 |
anim/ | 定義漸變動畫的XML文件 |
color/ | 定義顏色狀態(tài)列表的XML文件 |
drawable/ | 位圖文件(.png浸间、.9.png太雨、.jpg、.gif) |
values/ | 包含字符串魁蒜、整型數(shù)和顏色等簡單值的 XML 文件囊扳。 |
mipmap/ | 適用于不同啟動器圖標(biāo)密度的可繪制對象文件。 |
layout/ | 用于定義用戶界面布局的XML文件 |
menu/ | 用于定義應(yīng)用菜單(如選項菜單兜看、上下文菜單或子菜單)的 XML 文件锥咸。 |
raw/ | 要以原始形式保存的任意文件,要以原始的InputStream打開這些資源 |
xml/ | 可以在運行時通過調(diào)用 Resources.getXML() 讀取的任意 XML 文件细移。各種 XML 配置文件(如可搜索配置)都必須保存在此處 |
values/目錄下的資源
其他 res/ 子目錄中的 XML 資源文件是根據(jù) XML 文件名定義單個資源搏予,而 values/ 目錄中的文件可描述多個資源。對于此目錄中的文件弧轧,<resources> 元素的每個子元素均定義一個資源雪侥。例如,<string> 元素創(chuàng)建 R.string 資源精绎,<color> 元素創(chuàng)建 R.color 資源速缨。
目錄 | 資源類型 |
---|---|
arrays.xml | 用于資源數(shù)組(類型化數(shù)組) |
color.xml | 顏色值 |
dimens.xml | 尺寸值 |
string.xml | 字符串值 |
styles.xml | 樣式 |
2、備用資源
幾乎每個應(yīng)用都應(yīng)提供備用資源以支持特定的設(shè)備配置代乃。 例如旬牲,對于不同的屏幕密度和語言,應(yīng)分別包括備用可繪制對象資源和備用字符串資源搁吓。 在運行時原茅,Android 會檢測當(dāng)前設(shè)備配置并為應(yīng)用加載合適的資源。
- 在res/中創(chuàng)建一個以resources_name + config_qualifier形式命名的新目錄堕仔。
- resources_name: 是相應(yīng)默認資源的目錄名稱
- qualifier: 是指定要使用這些資源的各個配置的名稱
- 將相應(yīng)的備用資源保存在此新目錄下员咽。這些資源文件的名稱必須與默認資源文件完全一樣。
例如hdpi限定符表示該目錄中的資源適用于屏幕密度較高的設(shè)備贮预。其中每個可繪制對象目錄中的圖像已經(jīng)針對特定的屏幕密度調(diào)整大小贝室,但是文件名完全相同。這樣一來用于圖像資源的ID始終相同仿吞,但是Android系統(tǒng)會通過將設(shè)備配置信息與資源目錄名稱中的限定符進行比較滑频,選擇最符合當(dāng)前設(shè)備的各個資源版本。詳細可見官方文檔
限定符命名規(guī)則
- 單組資源可以指定多個限定符唤冈,并使用短劃線分隔峡迷。
- 不能嵌套備用資源目錄。
- 命名中的值不區(qū)分大小寫。
- 對于每種限定符類型绘搞,僅支持一個值彤避。
將備用資源保存到以這些限定符命名的目錄中之后,Android 會根據(jù)當(dāng)前設(shè)備配置在應(yīng)用中自動應(yīng)用這些資源夯辖。 每次請求資源時琉预,Android 都會檢查備用資源目錄是否包含所請求的資源文件,然后查找最佳匹配資源蒿褂。 如果沒有與特定設(shè)備配置匹配的備用資源圆米,則 Android 會使用相應(yīng)的默認資源(一組用于不含配置限定符的特定資源類型的資源)。
以下為系統(tǒng)決定使用哪個資源文件夾的邏輯
3啄栓、處理運行時變更
有些設(shè)備配置可能在運行時發(fā)生變化娄帖。此時,Android系統(tǒng)會重啟正在運行的Activity(先后調(diào)用onDestroy()和onCreate()方法)昙楚。重啟行為旨在通過利用與新設(shè)備配置匹配的備用資源自動重新加載您的應(yīng)用近速,來幫助它適應(yīng)新配置。對于Activity中數(shù)據(jù)可以在銷毀時通過onSaveInstanceState()進行保存堪旧,重啟時通過onRestoreInstanceState()恢復(fù)數(shù)據(jù)数焊,但是這樣的處理方式成本高昂,會給用戶留下糟糕的使用體驗崎场。
在配置變更期間保留對象
如果 Activity 因配置變更而重啟,則可通過保留 Fragment 來減輕重新初始化 Activity 的負擔(dān)遂蛀。此片段可能包含對您要保留的有狀態(tài)對象的引用谭跨。
當(dāng) Android 系統(tǒng)因配置變更而關(guān)閉 Activity 時,不會銷毀您已標(biāo)記為要保留的 Activity 的片段李滴。 您可以將此類片段添加到 Activity 以保留有狀態(tài)的對象螃宙。
- 擴展Fragment類并聲明對有狀態(tài)的對象的引用
- 在創(chuàng)建片段后調(diào)用saveRetainInstance(boolean)
- 將片段添加到Activity中
- 重啟Activity后,使用FragmentManager檢索片段
public class RetainedFragment extends Fragment {
// data object we want to retain
private MyDataObject data;
// this method is only called once for this fragment
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// retain this fragment
setRetainInstance(true);
}
public void setData(MyDataObject data) {
this.data = data;
}
public MyDataObject getData() {
return data;
}
}
使用 FragmentManager 將片段添加到 Activity所坯。在運行時配置變更期間再次啟動 Activity 時谆扎,您可以獲得片段中的數(shù)據(jù)對象。
public class MyActivity extends Activity {
private RetainedFragment retainedFragment;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// find the retained fragment on activity restarts
FragmentManager fm = getFragmentManager();
retainedFragment = (RetainedFragment) fm.findFragmentByTag(“data”);
// create the fragment and data the first time
if (retainedFragment == null) {
// add the fragment
retainedFragment = new RetainedFragment();
fm.beginTransaction().add(retainedFragment, “data”).commit();
// load the data from the web
retainedFragment.setData(loadMyData());
}
// the data is available in retainedFragment.getData()
...
}
@Override
public void onDestroy() {
super.onDestroy();
// store the data in the fragment
retainedFragment.setData(collectMyLoadedData());
}
}
自行處理配置更新
如果應(yīng)用在特定配置變更期間無需更新資源芹助,并且因性能限制您需要盡量避免重啟堂湖,則可聲明 Activity 將自行處理配置變更向族,這樣可以阻止系統(tǒng)重啟 Activity樟结。要聲明由 Activity 處理配置變更,請在清單文件中編輯相應(yīng)的 <activity> 元素檀轨,以包含 android:configChanges 屬性以及代表要處理的配置的值蒙谓〕饧荆可以在該屬性中聲明多個配置值,通過“|”字符分隔這些配置值。
當(dāng)其中一個配置發(fā)生變化時酣倾,Activity不會重啟舵揭。而是,Activity會收到一個對onConfigrationChanged()的調(diào)用躁锡。這個方法會有一個Configration對象的參數(shù)指定對新設(shè)備的配置午绳,可以通過對Configration中的字段確定新配置。調(diào)用此方法時稚铣,Activity 的 Resources 對象會相應(yīng)地進行更新箱叁,以根據(jù)新配置返回資源,這樣惕医,您就能夠在系統(tǒng)不重啟 Activity 的情況下輕松重置 UI 的元素耕漱。
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Checks the orientation of the screen
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
}
}