您好,登錄后才能下訂單哦!
在xx手機上速配出現(xiàn)bug修復(fù)的任務(wù),軟件在xx手機上打開,跳過一個界面,就把上一個界面給Kill了,剛開始以為是xx手機修改了android系統(tǒng),后來發(fā)現(xiàn)是手機太爛了,內(nèi)存太低了,每次跳轉(zhuǎn)都因內(nèi)存不足把上個界面給Kill了,正好讓我復(fù)習(xí)和實際運用一下Activity中的onSaveInstanceState方法和onRestoreInstanceState方法!
紙上得來終覺淺,絕知此事要躬行!以前在網(wǎng)上學(xué)習(xí)了onSaveInstanceState方法和onRestoreInstanceState方法,一直都很少機會體驗它存在的場景,沒有深刻的體會,這次讓我再次感受到學(xué)習(xí)開發(fā)就是理論后要多實踐,不管多難都要上手去做,才能更深刻的理解那些理論原理!
1、讓程序出現(xiàn)被系統(tǒng)kill的場景,而且onSaveInstanceState方法和onRestoreInstanceState方法都調(diào)用!
A、運行你的程序,當(dāng)程序打開時,按HOME鍵,這時系統(tǒng)會調(diào)用onSaveInstanceState方法,注意:這個方法的調(diào)用是系統(tǒng)決定的,不是軟件或者其他什么因素,系統(tǒng)覺得有可能在某個時間因內(nèi)存不足等因素而Kill掉你,所以給你個機會讓你現(xiàn)在先利用這個方法保存下數(shù)據(jù),所以調(diào)用onSaveInstanceState方法。
B、一般情況下,即使你在onSaveInstanceState保存了數(shù)據(jù),在系統(tǒng)沒Kill掉程序的情況下,你再回到剛關(guān)閉的界面,你也會感覺剛才調(diào)用onSaveInstanceState方法保存的數(shù)據(jù)沒什么作用,只有在系統(tǒng)kill掉程序的情況下,再回到剛關(guān)閉的界面,回調(diào)了onRestoreInstanceState方法,這時onSaveInstanceState方法保存的數(shù)據(jù),才發(fā)揮真正的作用,如何重現(xiàn)這種場景呢,利用DDMS替系統(tǒng)干這件壞事,kill掉你的程序:在按下HOME鍵后,系統(tǒng)已經(jīng)調(diào)用你的onSaveInstanceState方法,打開DDMS找到你的程序進程,stop你的進程,再打開程序!
注意:Activity調(diào)用OnCreate方法來初始化界面,它在onRestoreInstanceState方法之前調(diào)用!
2、如果從MainActivity中通過Intent攜帶數(shù)據(jù)打開BActivity,BActivity界面被系統(tǒng)kill后,重新創(chuàng)建BActivity后之前攜帶的數(shù)據(jù)是會還原的,但該界面被殺之前對傳過來的數(shù)據(jù)做的任何修改都作廢!
3、onSaveInstanceState方法的參數(shù)(Bundle savedInstanceState) == onRestoreInstanceState方法參數(shù)(Bundle savedInstanceState) == onCreate方法參數(shù)(Bundle savedInstanceState) ,第一次創(chuàng)建Activity時,調(diào)用onCreate方法,傳進來的參數(shù)是為null,但如果出現(xiàn)被系統(tǒng)kill又被重建時調(diào)用onCreate的場景,onCreate方法的參數(shù)就是onSaveInstanceState方法和onRestoreInstanceState方法參數(shù)的值!通過在onCreate方法判斷if(savedInstanceState
== null ) 是否被重建并存有數(shù)據(jù)!
4、界面上的View也都有onSaveInstanceState方法和onRestoreInstanceState方法,系統(tǒng)也是通過調(diào)用它們來存儲界面和恢復(fù)界面的數(shù)據(jù),系統(tǒng)會調(diào)用Activity對應(yīng)的onSaveInstanceState方法之前調(diào)用界面View的onSaveInstanceState方法!
BActivity.java
private ArrayList<String> main = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.b);
if (savedInstanceState == null) {
Log.i("kill", "onCreate savedInstanceState = null 第一次創(chuàng)建BACtivity");
main = (ArrayList<String>)(getIntent().getExtras().get("main"));
Log.i("kill", "從MainActivity傳過來的值 main = " +
""+main.toString());
//往傳過來的ArrayList<String>對象填充數(shù)據(jù)
main.add("add String");
}else{
Log.i("kill", "BACtivity被殺后的重建 onCreate savedInstanceState的值 = " +
"onSaveInstanceState savedInstanceState的值 = onRestoreInstanceState" +
"savedInstanceState 的值= "+savedInstanceState.getString("save"));
main = (ArrayList<String>)(getIntent().getExtras().get("main"));
Log.i("kill", "BACtivity被殺后的重建 獲得之前從MainActivity傳過來的值 main=" +
""+main.toString());
}
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onRestoreInstanceState(savedInstanceState);
Log.i("kill", "BACtivity的onRestoreInstanceState方法被調(diào)用"+main.toString());
savedInstanceState.getString("save");
}
@Override
protected void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
super.onSaveInstanceState(outState);
Log.i("kill", "BACtivity的onSaveInstanceState方法被調(diào)用 存在main中的數(shù)據(jù) = "+main.toString());
outState.putString("save", "come from onSaveInstanceState");
}
CustomView.java:只是繼承了Button,重寫了Button的onSaveInstanceState方法和onRestoreInstanceState方法
@Override
public Parcelable onSaveInstanceState() {
// TODO Auto-generated method stub
Log.i("kill", "CustomView onSaveInstanceState被調(diào)用");
return super.onSaveInstanceState();
}
@Override
public void onRestoreInstanceState(Parcelable state) {
// TODO Auto-generated method stub
Log.i("kill", "CustomView onRestoreInstanceState被調(diào)用");
super.onRestoreInstanceState(state);
}
5、從BActivity打開CActivity用StartActivityForResult方法要求CActivity finish時回傳數(shù)據(jù)回BActivity,在跳轉(zhuǎn)到CActivity后BActivity被系統(tǒng)Kill了,當(dāng)CActivity finish時,系統(tǒng)重建BActivity,onActivityResult方法依然能收到上個界面回傳的數(shù)據(jù)?。ㄟ@個場景的出現(xiàn)就是在CActivity界面時用DDMS kill程序,重建CActivity再從CActivity回到BActivity就可以看到BActivity被重建,依然可以獲得CActivity回傳的數(shù)據(jù))上代碼
BACtivity.java
Button bBtn = (Button)findViewById(R.id.b_btn);
bBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(BActivity.this, CActivity.class);
startActivityForResult(intent, 0);
}
});
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if (isKill) {
Log.i("kill", "BACtivity被kill后重新創(chuàng)建的值 =" +
""+data.getExtras().getString("c"));
}else{
Log.i("kill", "BACtivity沒被kill調(diào)用的值=" +
""+data.getExtras().getString("c"));
}
}
CActivity.java
Button cBtn = (Button)findViewById(R.id.c_btn);
cBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// finish自己,并回傳數(shù)據(jù)給BActivity
Intent data = new Intent();
data.putExtra("c", "comfrom CActivity");
CActivity.this.setResult(Activity.RESULT_OK, data);
finish();
}
});
結(jié)論:
1、從A界面-->B界面-->C界面,用A界面通過Intent傳過來的數(shù)據(jù),即使B界面到C界面后B界面被殺了,再回到B界面,B界面還是拿得到A界面?zhèn)鬟^來的數(shù)據(jù),但還是原始Intent的數(shù)據(jù),如果B界面在被殺之前對Intent數(shù)據(jù)加工,通過onSaveInstanceState存儲,通過onRestoreInstanceState統(tǒng)一處理了,那么就要繞過之前A界面通過Intent傳過來的原始數(shù)據(jù)的干擾。
2、B界面-->C界面,B界面被kill了,C界面finish后,系統(tǒng)重建B界面,依然能拿到C界面回傳的數(shù)據(jù)。
3、注意onCreate(Bundle saveInstanceSate)方法參數(shù)Bundle saveInstanceSate的作用
4、View也有onSaveInstanceState方法和onRestoreInstanceState方法
源代碼:http://download.csdn.net/detail/ak5700/6661497
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。