一個(gè)好的app,在人性化的體驗(yàn)上,有一個(gè)功能不可缺少,那就是軟件的自我恢復(fù)。
如果仔細(xì)觀察的人,你會(huì)發(fā)現(xiàn)。一些好的app,在Android手機(jī)上長(zhǎng)期留在后臺(tái)(自己強(qiáng)制銷毀的不算),再次啟動(dòng)的時(shí)候,它仍然能打開(kāi)你上一次保留的界面,保留的數(shù)據(jù),能進(jìn)行返回上個(gè)界面進(jìn)行正常的操作。
如果一些比較普通的app,如果按照上面同樣的操作的話。要么會(huì)丟失一些數(shù)據(jù),甚至?xí)W退。
那么這次我們就是講如何在當(dāng)前app因?yàn)閮?nèi)存不足而銷毀的時(shí)候,再次啟動(dòng)該app,如何自我恢復(fù)?
1.Android自己也有恢復(fù)的。
在講這個(gè)之前,我們先講Android是怎么處理的,老樣子,官方圖
是的,Android自己做了這方面的處理,但是,只限于簡(jiǎn)單的控件恢復(fù),而且這些控件是有ID的才能進(jìn)行恢復(fù)。
2.那看看代碼是什么時(shí)候銷毀、恢復(fù)(下面對(duì)Activity,Fragment一樣)
銷毀一般分為兩種情況:
- 如果用戶點(diǎn)擊返回按鈕或通過(guò)代碼調(diào)用關(guān)閉時(shí),這屬于正常銷毀。
- 如果當(dāng)前界面長(zhǎng)期未使用,或者當(dāng)前app待在后臺(tái)的時(shí)候,其他app需要更多資源以致系統(tǒng)必須關(guān)閉后臺(tái)進(jìn)程恢復(fù)內(nèi)存,系統(tǒng)也可能會(huì)銷毀當(dāng)前app,這屬于非正常銷毀,盡管app被銷毀,但系統(tǒng)會(huì)保存其狀態(tài),這樣,如果用戶點(diǎn)擊后臺(tái)返回該Activity,系統(tǒng)會(huì)使用保存了該app被銷毀時(shí)的狀態(tài)數(shù)據(jù)來(lái)創(chuàng)建新的app。
屏幕旋轉(zhuǎn)、鍵盤可用性改變、 語(yǔ)言改變都會(huì)導(dǎo)致第二種情況出現(xiàn)。
合格的測(cè)試,是會(huì)著重測(cè)試這方面的那么如何模擬呢,很簡(jiǎn)單的,打開(kāi)手機(jī)的設(shè)置->開(kāi)發(fā)者選項(xiàng)->不保留活動(dòng)開(kāi)關(guān)打開(kāi)
3.非法銷毀恢復(fù)的生命周期
onPause -> onSaveInstanceState -> onStop -> onDestroy -> onCreate -> onStart -> onRestoreInstanceState -> onResume
可以看到onSaveInstanceState(銷毀前保存數(shù)據(jù)) 和onRestoreInstanceState (恢復(fù)后取數(shù)據(jù))
當(dāng)你的app當(dāng)前activity開(kāi)始被停止時(shí),系統(tǒng)會(huì)調(diào)用onSaveInstanceState()方法,以便你的Activity可以使用Bundle保存數(shù)據(jù)。而super.onSaveInstanceState(savedInstanceState)也做了我剛才所說(shuō)的簡(jiǎn)單控件的狀態(tài)保存,例如EditText中的文本信息或ListView的滾動(dòng)位置。例如:
public class MainActivity extends Activity {
static final String DATA = "data";
private String data = "模擬數(shù)據(jù)";
@Override
protected void onSaveInstanceState(Bundle savedInstanceState) {
// Save custom values into the bundle
savedInstanceState.putString(DATA , data);
// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}
}
那么有保存自然有恢復(fù)了
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
// Always call the superclass so it can restore the view hierarchy
super.onRestoreInstanceState(savedInstanceState);
// Restore state members from saved instance
data= savedInstanceState.getString(DATA);
}
4.當(dāng)然少不了Fragment
Fragment也有onSaveInstanceState,但是恢復(fù)數(shù)據(jù)則是onCreateView,有一個(gè)參數(shù)是Bundle savedInstanceState就是了。