在上一篇中说,用实例说明了Activity的生命周期,从onCreate()到onDestroy(),以及当按下home键,按下Call键弹出对话框时,Activity的生命周期,接下来给大家分享,深入Activity生命周期。
还是上面这个(二)中的例子,如果我们在EditText中编辑了一些文字,如:
当切换手机横屏时,发现结果如下:
EditText中的数据没有了, 在这个屏幕切换过程中Activity的生命周期是什么样子的呢?我们来分析一下,还是先来看log,
07-31 06:39:46.820: INFO/my(1498): onCreate--- 07-31 06:39:46.820: INFO/my(1498): onStart--- 07-31 06:39:46.830: INFO/my(1498): onResume--- 07-31 06:40:30.089: INFO/my(1498): onSaveInstanceState--- 07-31 06:40:30.089: INFO/my(1498): onPause--- 07-31 06:40:30.089: INFO/my(1498): onStop--- 07-31 06:40:30.089: INFO/my(1498): onDestroy--- 07-31 06:40:30.199: INFO/my(1498): onCreate--- 07-31 06:40:30.209: INFO/my(1498): onStart--- 07-31 06:40:30.209: INFO/my(1498): onResume---
发现在切换屏幕时,先调用了onSaveInstanceState(),这个函数式用来保存状态的,数据就存放在bundle中,保存的数据会同时发送给onCreate()和onRestoreInstanceState()。
保存数据后会先暂停Activity 然后停止,销毁程序,然后重新创建Acitivty,在这个过程中,新的Activity中的EditText和过去的Activity中EditText不是同一个,因为在不同Context中,
而且是新创建出来的。过去的EditText中有数据,但是这个数据在新创建出来的EditText中是没有保存的,因此新的EditText中是没有数据的。如果我们需要保存这个数据,该怎么做?
从log中可以知道,函数onSaveInstanceState(),是用来保存状态的,因此我们可以在onSaveInstanceState()中添加代码:
@Override protected void onSaveInstanceState(Bundle outState) { // TODO Auto-generated method stub super.onSaveInstanceState(outState); String str = et.getText().toString(); Log.i("my", "onSaveInstanceState---str="+str); outState.putString("content", str); }
有同学会问,那么我们再Bundle中把数据放进去了,在哪里取出来,然后把数据填充到EditText中呢?
其实在2.2的版本中,实测实验表明我们只需给EditText添加Id即可,系统自动把原有数据填充到EditText中,切换屏幕实验一下,截图如下:
这里有很多博文中讲到需要在onSaveInstanceState()中做数据保存的工作,指的是一些复杂操作,而如果是简单的控件保存原来的数据,则只需添加控件Id即可。大家可以亲测下。
当然如果需要做复杂点操作,比如我们需要将整个EditText数据取出来,或者其他的,这里提供给大家一个例子,可以试试
代码如下:
1 public class AaaaaaActivity extends Activity { 2 3 EditText et; 4 TextView tv; 5 static boolean orientation = false; 6 7 8 /** Called when the activity is first created. */ 9 @Override 10 public void onCreate(Bundle savedInstanceState) { 11 super.onCreate(savedInstanceState); 12 setContentView(R.layout.main); 13 initUI(); 14 Log.i("my", "orientation---"+orientation ); 15 if(orientation) 16 { 17 String str = savedInstanceState.getString("content"); 18 Log.i("my", "str---"+str ); 19 } 20 Log.i("my", "onCreate---" ); 21 } 22 23 24 private void initUI() 25 { 26 et = (EditText)findViewById(R.id.et); 27 tv = (TextView)findViewById(R.id.tv); 28 } 29 30 @Override 31 protected void onRestart() 32 { 33 // TODO Auto-generated method stub 34 super.onRestart(); 35 Log.i("my", "onRestart---"); 36 } 37 38 39 @Override 40 protected void onStart() 41 { 42 // TODO Auto-generated method stub 43 super.onStart(); 44 Log.i("my", "onStart---"); 45 } 46 47 48 @Override 49 protected void onResume() 50 { 51 // TODO Auto-generated method stub 52 super.onResume(); 53 Log.i("my", "onResume---"); 54 } 55 56 57 @Override 58 protected void onSaveInstanceState(Bundle outState) 59 { 60 // TODO Auto-generated method stub 61 super.onSaveInstanceState(outState); 62 String str = et.getText().toString(); 63 Log.i("my", "onSaveInstanceState---str="+str ); 64 outState.putString("content", str); 65 orientation = true; 66 } 67 68 @Override 69 protected void onRestoreInstanceState(Bundle savedInstanceState) 70 { 71 // TODO Auto-generated method stub 72 super.onRestoreInstanceState(savedInstanceState); 73 Log.i("my", "onRestoreInstanceState---"); 74 String str = savedInstanceState.getString("content"); 75 Log.i("my", "content="+str); 76 } 77 78 79 @Override 80 protected void onPause() 81 { 82 83 // TODO Auto-generated method stub 84 super.onPause(); 85 Log.i("my", "onPause---"); 86 } 87 88 @Override 89 protected void onStop() 90 { 91 // TODO Auto-generated method stub 92 super.onStop(); 93 Log.i("my", "onStop---"); 94 } 95 96 @Override 97 protected void onDestroy() 98 { 99 // TODO Auto-generated method stub 100 super.onDestroy(); 101 Log.i("my", "onDestroy---"); 102 } 103 }
(为什么不能上传附件??)
分析log,证实onSaveInstanceState()会在onStart(),和onResume()之间执行。
附:
如果需要设置横屏不重启Activity,那么在manifest中注明 :
android:configChanges="orientation|keyboardHidden"
又或者根本不允许屏幕切换只能竖屏,设置如下:
android:screenOrientation=”landscape”
只能横屏,设置如下:
android:screenOrientation=”portrait”