Runtime Changes包括orientation,鍵盤(pán)可見(jiàn)性,語(yǔ)言設(shè)置等,這些內(nèi)容發(fā)生變化后,
系統(tǒng)將重啟Activity(先執(zhí)行onDestroy,再執(zhí)行onCreate),以便APP可以響應(yīng)
這些變化。
onSaveInstanceState()和onRestoreInstanceState()回調(diào)在這種情形下可以
使得APP能保存已有狀態(tài),在Activity重新創(chuàng)建時(shí)能夠恢復(fù)已有狀態(tài),為用戶提供一致的體驗(yàn)。
如果需要把已加載的數(shù)據(jù)應(yīng)用到新的狀態(tài)中,有兩種方式:
onSaveInstanceState()和onRestoreInstanceState()并不是設(shè)計(jì)用來(lái)傳遞大量數(shù)據(jù)的,
其傳遞的Bundle對(duì)象有大小限制。而且Bundle中的數(shù)據(jù)都會(huì)先反序列化再序列化,耗時(shí)較多。
可以使用Fragment,調(diào)用Fragment::setRetainInstance(true),在Activity重新創(chuàng)建之后,
通過(guò)FragmentManager獲取到重用的Fragment對(duì)象,進(jìn)而獲取到已有的數(shù)據(jù)。這里需要注意的是,
Fragment不能直接或者間接持有Activity的引用,否則可能會(huì)導(dǎo)致老的Activity對(duì)象的內(nèi)存泄漏。
利用這一方式,有一種HeadlessFragment的用法,這個(gè)Fragment沒(méi)有UI,只負(fù)責(zé)后臺(tái)加載數(shù)據(jù),
它不會(huì)因?yàn)锳ctivity的配置變化銷毀而銷毀,可以保證數(shù)據(jù)獲取過(guò)程的連續(xù)性。
Activity可以在manifest中聲明自行處理配置變化,同時(shí)onConfigurationChanged()回調(diào)會(huì)
在配置變化時(shí)被執(zhí)行。這種方式是最為復(fù)雜的,應(yīng)該是最后的考慮選項(xiàng)。
android:configChanges="orientation|screenSize|keyboardHidden"
配置發(fā)生變化之后,getResources()函數(shù)返回的對(duì)象是新配置下的資源對(duì)象,可以直接使用,
相比于上述通過(guò)Fragment保留數(shù)據(jù)的方式,更建議使用Loaders進(jìn)行替換。Loaders自安卓3.0引入, 用于異步加載數(shù)據(jù),Activity和Fragment均可以使用。
Loader框架包含了一個(gè)CursorLoader實(shí)現(xiàn),包括了異步請(qǐng)求數(shù)據(jù),Activity/Fragment銷毀重新
創(chuàng)建時(shí)直接返回已有數(shù)據(jù)等功能。
LoaderTestCase類,用于測(cè)試;AndroidJUnitTestRunner執(zhí)行的;