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