• Activity的生命周期


          今天对于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)就是上面的两张图,一个正常活动生命周期的图,一个异常下活动生命周期的图。

  • 相关阅读:
    Edge 修改使用的默认搜索引擎
    VSCode 插件之
    Visual Studio Code 插件之
    一个随笔
    COGS 2479 偏序 题解
    [NOIP2015] 子串substring 题解
    [CQOI2011]动态逆序对
    树套树三题 题解
    一个随笔
    HEOI 2016 游记
  • 原文地址:https://www.cnblogs.com/fuly550871915/p/5003675.html
Copyright © 2020-2023  润新知