美文网首页
378,android中Activity生命周期,函数调用顺序(

378,android中Activity生命周期,函数调用顺序(

作者: 枫叶1234 | 来源:发表于2020-12-25 11:18 被阅读0次
    image.png 截屏2020-12-11 下午8.46.16.png 截屏2020-12-11 下午8.47.01.png

    一个Activity从本质上讲拥有4种状态:

    • 运行:如果当前的activity在前台界面上时(堆栈顶端)。
    • 暂停:如果activity被另一个非全屏活动强占焦点并覆盖时(如弹窗dialog),它将会暂停。一个暂停的活动也是完全活跃的(它的所有的状态和成员信息将会保留,但activity本身将不会再依附于WindowsManager了),在内存极度缺乏的状态会被系统杀死。
    • 停止:如果activity完全被另一个全屏活动遮挡住时,它将会停止。该活动也仍保留全部的状态和成员信息,但将会被隐藏起来不再展示给用户,并且当内存在其他地方被需要时该活动就将会被系统杀死。
    • 重启:如果activity处于暂停或者停止状态,系统将会在内存中终止该活动无论是结束活动或者杀死进程。当它再一次展示给用户时,它必须是完全重启并且恢复到之前的状态。

    状态转换

    image.png

    这张图从Activity的起点是从Activity running开始的

    上图中我们可以看到Activity在生命周期状态进行转换的过程中,activity本身是在什么时候调用的onSaveInstanceState()方法与onRestoreInstanceState()方法来进行重要信息的存储与恢复的。因为在蜂巢版本之前onSaveInstanceState()方法只有在activity异常退出时才会调用,所以我们应该在onPause()方法中进行信息持久化存储的操作,在蜂巢之后的版本,生命周期就可以正常的调用onSaveInstanceState()方法来进行信息持久化存储的操作了。

    部分实例列举

    上面说了一堆Activity生命周期的定义,在实际应用中,我们更倾向于实践运用,所以我会列举部分实例。大家可以给我点个小星星

    • 打开activity关闭activity生命周期如下(启动与销毁)
    // activity启动
    05-24 11:16:44.124 16259-16259/com.perry.activitylifecycle E/TAG lifecycle:  ------>>> onCreate
    05-24 11:16:44.125 16259-16259/com.perry.activitylifecycle E/TAG lifecycle:  ------>>> onStart
    05-24 11:16:44.125 16259-16259/com.perry.activitylifecycle E/TAG lifecycle:  ------>>> onResume
    // activity关闭
    05-24 11:16:46.691 16259-16259/com.perry.activitylifecycle E/TAG lifecycle:  ------>>> onPause
    05-24 11:16:47.038 16259-16259/com.perry.activitylifecycle E/TAG lifecycle:  ------>>> onStop
    05-24 11:16:47.038 16259-16259/com.perry.activitylifecycle E/TAG lifecycle:  ------>>> onDestroy
    

    可以看到正常的启动与关闭Activity不会调用onSaveInstanceState(Bundle)方法与onRestoreInstanceState(Bundle)方法,所以如果要离开该界面时,该界面的重要信息,我们要在onPause()或onStop()方法中进行存储。

    • 弹窗(dialog、popupwindow)
    [空]
    

    没错,你没看错。是空!因为dialog与popupwindow实际上是一个存在于这个activity上的控件,所以它并不会影响activity本身的生命周期!试想如果你每次弹窗你的activity都要走onPause方法的话,那你的一些存储持久化操作是不是会不停地无更新的存储呢?所以,不要被一些说法误导,如果你不知道,那么就去动手实践。

    • 打开Dialog样式的Activity(暂停状态)
    // 在Manifest文件中首先设置dialog样式
    <activity android:name=".TranslateActivity"
            android:theme="@style/Theme.AppCompat.Dialog">
    </activity>
    // 然后你懂得,我们来打开这个dialog样式的Activity
    05-24 16:27:24.964 26913-26913/com.perry.activitylifecycle E/TAG lifecycle:  ------>>> onPause
    05-24 16:27:25.206 26913-26913/com.perry.activitylifecycle E/TAG lifecycle:  ------>>> onSaveInstanceState
    // 最后我们关闭这个Activity
    05-24 16:27:28.227 26913-26913/com.perry.activitylifecycle E/TAG lifecycle:  ------>>> onResume
    
    • 屏幕旋转
    05-24 11:24:47.377 16724-16724/com.perry.activitylifecycle E/TAG lifecycle:  ------>>> onPause
    05-24 11:24:47.378 16724-16724/com.perry.activitylifecycle E/TAG lifecycle:  ------>>> onSaveInstanceState
    05-24 11:24:47.378 16724-16724/com.perry.activitylifecycle E/TAG lifecycle:  ------>>> onStop
    05-24 11:24:47.378 16724-16724/com.perry.activitylifecycle E/TAG lifecycle:  ------>>> onDestroy
    05-24 11:24:47.451 16724-16724/com.perry.activitylifecycle E/TAG lifecycle:  ------>>> onCreate
    05-24 11:24:47.454 16724-16724/com.perry.activitylifecycle E/TAG lifecycle:  ------>>> onStart
    05-24 11:24:47.454 16724-16724/com.perry.activitylifecycle E/TAG lifecycle:  ------>>> onRestoreInstanceState
    05-24 11:24:47.454 16724-16724/com.perry.activitylifecycle E/TAG lifecycle:  ------>>> onResume
    

    此处的onSaveInstanceState(Bundle)方法与onRestoreInstanceState(Bundle)方法具体执行时机,当targetSdkVersion小于3时onSaveInstanceState是在onPause方法中调用的,而大于3时是在onStop方法中调用的。而onRestoreInstanceState是在onStart之后、onResume之前调用的。

    • 按Home键后再开启app(停止状态)
    // 点击home键(菜单键)
    05-24 11:50:25.097 17817-17817/com.perry.activitylifecycle E/TAG lifecycle:  ------>>> onPause
    05-24 11:50:25.407 17817-17817/com.perry.activitylifecycle E/TAG lifecycle:  ------>>> onSaveInstanceState
    05-24 11:50:25.407 17817-17817/com.perry.activitylifecycle E/TAG lifecycle:  ------>>> onStop
    // 打开App
    05-24 11:51:05.471 17817-17817/com.perry.activitylifecycle E/TAG lifecycle:  ------>>> onRestart
    05-24 11:51:05.476 17817-17817/com.perry.activitylifecycle E/TAG lifecycle:  ------>>> onStart
    05-24 11:51:05.476 17817-17817/com.perry.activitylifecycle E/TAG lifecycle:  ------>>> onResume
    

    下面我们就结合实例,来演示一下生命周期的几个过程的详细情况。我们新建一个名为lifecycle的项目,创建一个名为LifeCycleActivity的Activity,如下:

    
    package com.scott.lifecycle;
     
    import android.app.Activity;
    import android.content.Context;
    import android.content.Intent;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
     
    public class LifeCycleActivity extends Activity {
        
        private static final String TAG = "LifeCycleActivity";
        private Context context = this;
        private int param = 1;
        
        //Activity创建时被调用
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            Log.i(TAG, "onCreate called.");
            
            setContentView(R.layout.lifecycle);
            
            Button btn = (Button) findViewById(R.id.btn);
            btn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent(context, TargetActivity.class);
                    startActivity(intent);
                }
            });
        }
        
        //Activity创建或者从后台重新回到前台时被调用
        @Override
        protected void onStart() {
            super.onStart();
            Log.i(TAG, "onStart called.");
        }
        
        //Activity从后台重新回到前台时被调用
        @Override
        protected void onRestart() {
            super.onRestart();
            Log.i(TAG, "onRestart called.");
        }
        
        //Activity创建或者从被覆盖、后台重新回到前台时被调用
        @Override
        protected void onResume() {
            super.onResume();
            Log.i(TAG, "onResume called.");
        }
        
        //Activity窗口获得或失去焦点时被调用,在onResume之后或onPause之后
        /*@Override
        public void onWindowFocusChanged(boolean hasFocus) {
            super.onWindowFocusChanged(hasFocus);
            Log.i(TAG, "onWindowFocusChanged called.");
        }*/
        
        //Activity被覆盖到下面或者锁屏时被调用
        @Override
        protected void onPause() {
            super.onPause();
            Log.i(TAG, "onPause called.");
            //有可能在执行完onPause或onStop后,系统资源紧张将Activity杀死,所以有必要在此保存持久数据
        }
        
        //退出当前Activity或者跳转到新Activity时被调用
        @Override
        protected void onStop() {
            super.onStop();
            Log.i(TAG, "onStop called.");   
        }
        
        //退出当前Activity时被调用,调用之后Activity就结束了
        @Override
        protected void onDestroy() {
            super.onDestroy();
            Log.i(TAG, "onDestory called.");
        }
        
        /**
         * Activity被系统杀死时被调用.
         * 例如:屏幕方向改变时,Activity被销毁再重建;当前Activity处于后台,系统资源紧张将其杀死.
         * 另外,当跳转到其他Activity或者按Home键回到主屏时该方法也会被调用,系统是为了保存当前View组件的状态.
         * 在onPause之前被调用.
         */
        @Override
        protected void onSaveInstanceState(Bundle outState) {
            outState.putInt("param", param);
            Log.i(TAG, "onSaveInstanceState called. put param: " + param);
            super.onSaveInstanceState(outState);
        }
        
        /**
         * Activity被系统杀死后再重建时被调用.
         * 例如:屏幕方向改变时,Activity被销毁再重建;当前Activity处于后台,系统资源紧张将其杀死,用户又启动该Activity.
         * 这两种情况下onRestoreInstanceState都会被调用,在onStart之后.
         */
        @Override
        protected void onRestoreInstanceState(Bundle savedInstanceState) {
            param = savedInstanceState.getInt("param");
            Log.i(TAG, "onRestoreInstanceState called. get param: " + param);
            super.onRestoreInstanceState(savedInstanceState);
        }
    }
    

    onCreate()方法中的参数Bundle savedInstanceState 的意义用法

    Activity中有一个名称叫onCreate的方法。该方法是在Activity创建时被系统调用,是一个Activity生命周期的开始。可是有一点容易被忽视,就是onCreate方法的参数saveInsanceState。一般的程序开发中,很少用到这个参数。
    onCreate方法的完整定义如下:
    public void onCreate(Bundle saveInsanceState){
    super.onCreate(saveInsanceState);
    }

    Bundle类型的数据与Map类型的数据相似,都是以key-value的形式存储数据的。
    从字面上看saveInsanceState,是保存实例状态的。实际上,saveInsanceState也就是保存Activity的状态的。那么,saveInsanceState中的状态数据是从何处而来的呢?下面我们介绍Activity的另一个方法saveInsanceState。

    onsaveInsanceState方法是用来保存Activity的状态的。当一个Activity在生命周期结束前,会调用该方法保存状态。

    如下所示:
    public void onSaveInsanceState(Bundle saveInsanceState){
    super.onSaveInsanceState(saveInsanceState);
    }

    在实际应用中,当一个Activity结束前,如果需要保存状态,就在onsaveInsanceState中,将状态数据以key-value的形式放入到saveInsanceState中。这样,当一个Activity被创建时,就能从onCreate的参数saveInsanceState中获得状态数据。
    状态这个参数在实现应用中有很大的用途,比如:一个游戏在退出前,保存一下当前游戏运行的状态,当下次开启时能接着上次的继续玩下去。再比如:电子书程序,当一本小说被阅读到第199页后退出了(不管是内存不足还是用户自动关闭程序),当下次打开时,读者可能已忘记了上次已阅读到第几页了,但是,读者想接着上次的读下去。如果采用saveInstallState参数,就很容易解决上述问题。

    使用例子:

    
    import android.app.Activity;
    
     import android.os.Bundle;
    
     import android.util.Log 
    
    public class AndroidTest extends Activity {
         private static final String TAG = "MyNewLog"; 
    
        @Override
    
        public void onCreate(Bundle savedInstanceState) {
    
            super.onCreate(savedInstanceState);
    
            // If an instance of this activity had previously stopped, we can get the original text it started with.
    
            if(null != savedInstanceState)
    
            {//因为Activity的生命周期原因 ,if 语句放着不一定能执行得到 应该结合实际情况
    
                   int IntTest = savedInstanceState.getInt("IntTest");
    
                   String StrTest = savedInstanceState.getString("StrTest");
    
             }
    
            setContentView(R.layout.main); 
    
        }
    
          @Override
    
        public void onSaveInstanceState(Bundle savedInstanceState) {
    
            // Save away the original text, so we still have it if the activity needs to be killed while paused.
    
          savedInstanceState.putInt("IntTest", 0);
    
          savedInstanceState.putString("StrTest", "savedInstanceState test");
    
          super.onSaveInstanceState(savedInstanceState);
    
           }
    
       @Override
    
        public void onRestoreInstanceState(Bundle savedInstanceState) {
    
          super.onRestoreInstanceState(savedInstanceState);
    
          int IntTest = savedInstanceState.getInt("IntTest");
    
          String StrTest = savedInstanceState.getString("StrTest");
    
          }
    
    }
    
    

    小结

    文章中我们具体的了解了Activity的7大生命周期与4种本质状态,还有onSaveInstanceState(Bundle)方法与onRestoreInstanceState(Bundle)具体执行时机。便于我们更好的了解与利用Activity中的每一种生命周期方法。

    相关文章

      网友评论

          本文标题:378,android中Activity生命周期,函数调用顺序(

          本文链接:https://www.haomeiwen.com/subject/ujuwgktx.html