今天对于Activity的生命周期又有了一点深入的理解。做个总结吧。

一、正常情况下的生命周期

     什么叫正常情况下的生命周期呢?也就是我们经常了解的一个活动的正常的生命流程。不用过度解释,

总结如下:

 

(1)onCreate()方法

 

活动第一次创建时被调用。

 

(2)onStart()

 

活动由不可见变为可见的时候调用

 

(3)onResume()

 

当活动准备开始与用户交互时会触发该方法,一般只会在需要执行以下的操作时才重写该事件:

 

l 开始动画

 

l 开始监听GPS更新

 

l 显示一些相关的提示和对话框

 

l 注册广播监听

 

4onPause()

 

系统准备去启动或者恢复另外一个活动的时候调用。或者当活动被切换到后台时将触发该方法,一般我们需要在该事件做如下的事情:

 

l 保存用户未提交的数据

 

l 关闭或清除引用的资源

 

l 注销广播

 

l 如果存在正在显示的提示或者对话框,则必须利用.Dismiss()进行清除。

 

5onStop()

 

当该活动完全不可见的时候被调用。一般会由以下原因触发:

 

l 当一个新的活动打开,并覆盖该活动时

 

l 一个已存在的活动切换到前台时

 

l 活动被销毁时

 

 

 

OnStop不是每次都会被执行,如果内存低下时,系统将不会执行该事件,而是直接关闭该应用,所以大家在OnPause事件中就要保存好所以的参数等等。而不能依赖该事件。

 

(6)onDestroy()

 

活动销毁之前被调用

 

7onRestart()

 

当活动由停止状态变为运行状态时被调用。即当用户通过Home按钮将该用户切换到后台,并在之后又打开该应用则会触发该事件。一般也很少重写该方法。

 

 

     贴一张大家都知道的流程图吧,如下:

 

 

 

 

 

    需要极其注意的是:在onPause中执行的操作不能太耗时!

 

二、异常情况下活动的生命周期

      这个是重点要说的!什么是异常情况呢?不好说,比如因为资源相关的配置发生改变或者系统内存不足时,活动就

会被杀死。这就属于异常情况,总之一句话:活动被异常终止!最常见的就是下面的两种情况:

(1)横屏或者竖屏切换时。此时因为切换之间系统要对活动中的布局里面的图片进行更换(比如你可能会准备同样的两张

      图片,不同像素宽高,分别对应于横屏或者竖屏的情况),此时就会导致在切换时,活动被瞬间杀死又被瞬间重建!

(2)因为系统内存不足,活动被回收时。

      发生意外终止,系统做出的对策就是会将活动中的数据进行自动保存,然后再需要的时候再将活动创建出来恢复数据。

     因此,对应的生命周期如下图:

 

     也就是说在发生意外时,系统会自动调用onSaveInstanceState方法来保存数据,在需要的时候再会重新创建出这个活动,

然后自动调用onRestoreInstanceState方法来恢复数据。你可能会有疑问,一个活动中可能有一个TextView,还有一个按钮,

可能还有其他的,那么当活动意外终止,怎么来控制保存这些控件的数据呢?其实任何一个view都重写了onSaveInstanceState

和onRestoreInstanceState方法,你可以翻看源码,看看发生意外时,每一个view都会自动保存什么。这里不再多说。

 

     上面列出的两种意外情况下的活动的生命周期是一样的,都是如上图所示。系统内存不足,不好模拟。但是横屏和竖屏

比较好模拟。下面我们通过一个实际例子,来看看是不是真的如上面所述的那样。

 

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

     新建一个项目。修改其Manifest文件,加入横竖和竖屏切换的感应,如下:

 

 <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:screenOrientation="sensor"
            >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

 

 

 

     上面只贴出了修改的那段代码,黄色部分就是加入的自动切换横屏和竖屏的功能。

     下面再修改其MainActivity代码,如下:

 

 1 public class MainActivity extends ActionBarActivity {
 2 
 3     private static final String Tag = "MainActivity";
 4 
 5     @Override
 6     protected void onCreate(Bundle savedInstanceState) {
 7         super.onCreate(savedInstanceState);
 8         setContentView(R.layout.activity_main);
 9 
10         if(savedInstanceState != null)
11         {
12             String t = savedInstanceState.getString("save_test");
13             Log.e(Tag,t+"   "+"onCreate");
14         }
15 
16     }
17 
18     @Override
19     protected void onSaveInstanceState(Bundle outState) {
20         super.onSaveInstanceState(outState);
21 
22         String t = "save me  ";
23         Log.e(Tag,t+"onSaveInstanceState");
24         outState.putString("save_test",t);
25     }
26 
27     @Override
28     protected void onRestoreInstanceState(Bundle savedInstanceState) {
29         super.onRestoreInstanceState(savedInstanceState);
30 
31         String t = savedInstanceState.getString("save_test");
32         Log.e(Tag,t+"    "+"onRestoreInstanceState");
33     }
34 
35  
36 }

 

 

 

    代码中重写了onSaveInstanceState和onResoreInstanceState方法,然后就在各个方法中打印标签。

   下面运行一下程序,做如下的操作:

 

 

     也就是控制手机,做了一个横竖和竖屏的切换。我们来看一下打印结果,如下:

     通过打印结果,就会发现在横屏和竖屏切换时,确实是调用了保存数据和恢复数据的那些方法。而从再一次

调用了onCreate方法,就知道活动被重建了。

 

+++++++++++++++++++++++++++++++++++++++++++++++++++++++

    接着上面的分析,有没有方法让在横竖和竖屏切换时,不要重新创建活动呢??当然是肯定的。

其实很简单,只要在Manifest文件中加入configChanges属性即可。也就是当检测到confiChanges指定

的属性发生改变时,也不会再去重新创建活动了

 

 

       下面我们就修改代码,来测试一下。首先修改Manifest中的代码,如下:

 <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:screenOrientation="sensor"
            android:configChanges="orientation|screenSize">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

 

       可以看到,添加了一句(即黄色部分),即检测到方向发生改变或者屏幕的size改变,也不去重新创建活动。

这针对的就是横屏和竖屏的切换。

     然后修改MainActivity中的代码,如下:

 

 1 public class MainActivity extends ActionBarActivity {
 2 
 3     private static final String Tag = "MainActivity";
 4 
 5     @Override
 6     protected void onCreate(Bundle savedInstanceState) {
 7         super.onCreate(savedInstanceState);
 8         setContentView(R.layout.activity_main);
 9 
10         if(savedInstanceState != null)
11         {
12             String t = savedInstanceState.getString("save_test");
13             Log.e(Tag,t+"   "+"onCreate");
14         }
15 
16     }
17 
18     @Override
19     protected void onSaveInstanceState(Bundle outState) {
20         super.onSaveInstanceState(outState);
21 
22         String t = "save me  ";
23         Log.e(Tag,t+"onSaveInstanceState");
24         outState.putString("save_test",t);
25     }
26 
27     @Override
28     protected void onRestoreInstanceState(Bundle savedInstanceState) {
29         super.onRestoreInstanceState(savedInstanceState);
30 
31         String t = savedInstanceState.getString("save_test");
32         Log.e(Tag,t+"    "+"onRestoreInstanceState");
33     }
34 
35     @Override
36     public void onConfigurationChanged(Configuration newConfig) {
37         super.onConfigurationChanged(newConfig);
38         Log.e(Tag,"onConfigurationChanged");
39     }
40 }

 

 

 

      黄色部分是我们新增加的代码。然后运行程序,依然做一个横屏竖屏的切换操作,打印结果如下:

 

     我们这次只有onConfiguration这一个方法被调用。onSaveInstanceState方法和onRestoreInstanceState方法

都没有被调用,onCreate方法也没有,即没有再重新创建活动了。这提示我们,如果在横竖屏切换过程中,还想做一些

逻辑操作的话,可以放在onConfiguration方法中。

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

总结:(1)系统只在异常终止了Activity时,才会调用onSaveInstanceState和onRestoreInstanceState方法

               来恢复数据。因此我们可以重写这两个方法来防止活动被出现意外终止时,数据发生丢失。

         (2)如果使用了在Manifest文件中加入configChanges属性来监测发生变化时不再重新创建活动,那么

               onConfiguration方法会被自动回调,我们可以在这里实现相关逻辑。

         (3)就是上面的两张图,一个正常活动生命周期的图,一个异常下活动生命周期的图。

 

posted on 2015-11-28 22:56  fuly  阅读(4500)  评论(0编辑  收藏  举报