activity异常被系统杀死处理方法

时间:2022-01-05 00:44:55

从界面跳转后被系统Kill来看Activity的方法调用

2013年11月20日  ⁄ 综合 ⁄ 共 4845字 ⁄ 字号      ⁄ 评论关闭
<iframe id="cproIframe_u1788635_2" width="336" height="280" src="http://pos.baidu.com/acom?adn=3&amp;at=231&amp;aurl=&amp;cad=1&amp;ccd=32&amp;cec=UTF-8&amp;cfv=18&amp;ch=0&amp;col=zh-CN&amp;conBW=0&amp;conOP=1&amp;cpa=1&amp;dai=2&amp;dis=0&amp;ltr=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DK7lhmz93YQWc8vdCrWC8lvG0QHQbpSHLfK5MWrka9a6rTV9f6SqSbwxs0zYpjUhM%26wd%3D%26eqid%3Df5aaca8a0002e56300000002561c6072&amp;ltu=http%3A%2F%2Fwww.xuebuyuan.com%2F1720788.html&amp;lu_161=0&amp;lunum=6&amp;n=83099053_cpr&amp;pcs=1920x917&amp;pis=10000x10000&amp;ps=486x1186&amp;psr=1920x1080&amp;pss=1920x506&amp;qn=701155a875a71f41&amp;rad=&amp;rsi0=336&amp;rsi1=280&amp;rsi5=4&amp;rss0=%23FFFFFF&amp;rss1=%23FFFFFF&amp;rss2=%230000ff&amp;rss3=%23444444&amp;rss4=%23008000&amp;rss5=&amp;rss6=%23e10900&amp;rss7=&amp;scale=&amp;skin=tabcloud_skin_3&amp;stid=5&amp;td_id=1788635&amp;titFF=%E5%AE%8B%E4%BD%93&amp;titFS=12&amp;titTA=left&amp;tn=text_default_336_280&amp;tpr=1444700510084&amp;ts=1&amp;version=2.0&amp;xuanting=0&amp;dtm=BAIDU_DUP2_SETJSONADSLOT&amp;dc=2&amp;di=u1788635&amp;ti=%E4%BB%8E%E7%95%8C%E9%9D%A2%E8%B7%B3%E8%BD%AC%E5%90%8E%E8%A2%AB%E7%B3%BB%E7%BB%9FKill%E6%9D%A5%E7%9C%8BActivity%E7%9A%84%E6%96%B9%E6%B3%95%E8%B0%83%E7%94%A8%20%7C%20%E5%AD%A6%E6%AD%A5%E5%9B%AD&amp;tt=1444700510069.93.140.140" align="center,center" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" allowtransparency="true" style="margin: 0px; padding: 0px; border-width: 0px; background-color: transparent;"></iframe>

最近接到公司软件在xx手机上速配出现bug修复的任务,软件在xx手机上打开,跳过一个界面,就把上一个界面给Kill了,刚开始以为是xx手机修改了android系统,后来发现是手机太烂了,内存太低了,每次跳转都因内存不足把上个界面给Kill了,正好让我复习和实际运用一下Activity中的onSaveInstanceState方法和onRestoreInstanceState方法!

纸上得来终觉浅,绝知此事要躬行!以前在网上学习了onSaveInstanceState方法和onRestoreInstanceState方法,一直都很少机会体验它存在的场景,没有深刻的体会,这次让我再次感受到学习开发就是理论后要多实践,不管多难都要上手去做,才能更深刻的理解那些理论原理!

1、让程序出现被系统kill的场景,而且onSaveInstanceState方法和onRestoreInstanceState方法都调用!

A、运行你的程序,当程序打开时,按HOME键,这时系统会调用onSaveInstanceState方法,注意:这个方法的调用是系统决定的,不是软件或者其他什么因素,系统觉得有可能在某个时间因内存不足等因素而Kill掉你,所以给你个机会让你现在先利用这个方法保存下数据,所以调用onSaveInstanceState方法。

activity异常被系统杀死处理方法

B、一般情况下,即使你在onSaveInstanceState保存了数据,在系统没Kill掉程序的情况下,你再回到刚关闭的界面,你也会感觉刚才调用onSaveInstanceState方法保存的数据没什么作用,只有在系统kill掉程序的情况下,再回到刚关闭的界面,回调了onRestoreInstanceState方法,这时onSaveInstanceState方法保存的数据,才发挥真正的作用,如何重现这种场景呢,利用DDMS替系统干这件坏事,kill掉你的程序:在按下HOME键后,系统已经调用你的onSaveInstanceState方法,打开DDMS找到你的程序进程,stop你的进程,再打开程序!

activity异常被系统杀死处理方法

activity异常被系统杀死处理方法

注意: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);
}

activity异常被系统杀死处理方法

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();
}
});

activity异常被系统杀死处理方法

结论:

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