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