美文网首页
小记Activity生命周期(onCreate)

小记Activity生命周期(onCreate)

作者: bridegg | 来源:发表于2017-11-15 16:19 被阅读0次

    干了Android将近有4年,发现自己的技术在一年前就停滞不前,于是乎准备从头开始巩固下自己之前学到的东西,然后利用文章的形式,寻找自己对于Android了解不太清除的地方。

    作为一个初级Android开发者想必应该看过这张图

    image

    这张图是developer.android里Activity介绍最著名的生命周期图

    如图所示 Activity共有7大生命周期(13年初级程序员在面试的时候经常问的问题),onCreate,onStart,onResume,onRestart,onPause,onStop,onDestroy。

    onCreate

    首先,我们来看onCreate。官网给onCreate做了一段解释

    Called when the activity is first created. This is where you should do all of your normal static set up: create views, bind data to lists, etc. This method also provides you with a Bundle containing the activity's previously frozen state, if there was one.

    Always followed byonStart().

    下面就由我这个英语不咋样的解释下这段话的意思(若有错误,欢迎指出)

    当Activity初次创建时,该方法会被调用,在这里去做一些普通的静态设置例如:创建View,绑定list的数据等等,如果之前存在activity并被冻结,该方法会返回一个Bundle包

    后面一般会跟随执行onStart()

    官方说的很简单,onCreate就是在初始化时调用,对于normal static set up我的理解就是不耗时的操作,这里也提到了返回Bundle包,这里的Bundle包配合onSaveInstanceState使用。**

    再来看Activity中onCreate的源码

    在Activity类里,onCreate会有两个方法:

    @MainThread

    @CallSuper

    protected void onCreate(@Nullable Bundle savedInstanceState)

    public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) { onCreate(savedInstanceState);

    }

    其中有两个参数的onCreate明显又调用了onCreate(savedInstanceState);

    所以首先我们来看onCreate的注释

    /** * Called when the activity is starting. This is where most initialization

    • should go: calling {@link #setContentView(int)} to inflate the

    • activity's UI, using {@link #findViewById} to programmatically interact

    • with widgets in the UI, calling

    • {@link #managedQuery(android.net.Uri , String[], String, String[], String)} to retrieve

    • cursors for data being displayed, etc. *

    *You can call {@link #finish} from within this function, in

    • which case onDestroy() will be immediately called without any of the rest

    • of the activity lifecycle ({@link #onStart}, {@link #onResume},

    • {@link #onPause}, etc) executing. *

    *Derived classes must call through to the super class's

    ** implementation of this method. If they do not, an exception will be thrown.*

    • @param savedInstanceState If the activity is being re-initialized after

    • previously being shut down then this Bundle contains the data it most

    • recently supplied in {@link #onSaveInstanceState}.

    Note: Otherwise it is null.

    *@see #onStart

    *@see #onSaveInstanceState

    *@see #onRestoreInstanceState

    *@see #onPostCreate */

    这段注释就写的比较详细了,首先也是告诉大家avtivity初始时会调用,后面这段讲解了什么是normal static set up,大多数是一些初始化:例如setContentView,findViewById,managedQuery(这个大家可能不熟悉,就是activity提供的一个数据处理功能,并且帮助我们管理Cursor的生命周期)

    第二段告诉大家,在onCreate里可以直接执行finish方法,并且会回调onDestroy,将不执行onStart,onResume,onPause等生命周期

    第三段告诉大家,关于实现继承报错的事情,无关紧要啦

    最后一段 主要讲了 savedInstanceState的用途(也就是官方文档说的Bundle)大体意思和官方文档说的差不多,需要onSaveInstanceState里设置Bundle的值,并且说明其他情况savedInstanceState的值均为空,最后附了几个链接。

    然后我们来看onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState)的注释

    /** * Same as {@link #onCreate(android.os.Bundle)} but called for those activities created with

    • the attribute {@link android.R.attr#persistableMode} set topersistAcrossReboots.
      *@param savedInstanceState if the activity is being re-initialized after
    • previously being shut down then this Bundle contains the data it most
    • recently supplied in {@link #onSaveInstanceState}.

    Note: Otherwise it is null.
    *@param persistentState if the activity is being re-initialized after

    • previously being shut down or powered off then this Bundle contains the data it most
    • recently supplied to outPersistentState in {@link #onSaveInstanceState}.

    Note: Otherwise it is null.
    *@see #onCreate(android.os.Bundle)

    • @see #onStart * @see #onSaveInstanceState * @see #onRestoreInstanceState * @see #onPostCreate */

    注释说明该方法和onCreate(android.os.Bundle)差不多,但是多出一个savedInstanceState 的参数,并且说明了将persistableMode这个属性设置为persistAcrossReboots时才会调用该方法,我查了下资料,说这个persistableMode是5.0后提供的为了数据持久化做的新的actvitiy属性。
    persistableMode分为三个值persistNever(不启用)persistRootOnly(根activity或task中)persistAcrossReboots(重启设备)

    这三个参数让我郁闷了很久,于是在6.0的小米机子上做了个实验,老是不灵,重启设备后永远拿不到存的值,后来做了如下处理

    首先我将activity的属性persistableMode设置成了

            <activity
                android:name=".test.activitys.AllActivitys"
                android:persistableMode="persistAcrossReboots"
                android:screenOrientation="portrait" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
    

    然后

    在activity里重写了如下代码

        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            Log.e(TAG, "onCreate");
            super.onCreate(savedInstanceState);
            setContentView(R.layout.test_activity);
            Toast.makeText(this, "onCreate", Toast.LENGTH_SHORT).show();
        }
    
        @Override
        public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {
            Log.e(TAG, "onCreate2");
    
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                if (persistentState != null) {
                    Log.e(TAG, "onCreate2  persistentState " + persistentState.getString("key"));
                }
                SharedPreferences sharedPreferences = getSharedPreferences("save", MODE_PRIVATE);
                String key = sharedPreferences.getString("key", "");
                Log.e(TAG, "onCreate2  sharedPreferences " + key);
                //清空之前存储的东西
                SharedPreferences.Editor editor = sharedPreferences.edit();
                editor.putString("key", "");
                editor.commit();
    
            }
            super.onCreate(savedInstanceState, persistentState);
            setContentView(R.layout.test_activity);
            Toast.makeText(this, "onCreate2", Toast.LENGTH_SHORT).show();
            info = (TextView) findViewById(R.id.info);
            info.setText(info.getText() + " " + System.currentTimeMillis() + "onCreate2 \n");
    
        }
    
      @Override
        public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
            Log.e(TAG, "onSaveInstanceState");
            Toast.makeText(this, "onSaveInstanceState", Toast.LENGTH_SHORT).show();
            info.setText(info.getText() + " " + System.currentTimeMillis() + "onSaveInstanceState \n");
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                outPersistentState.putString("key", "我是重启前的onSaveInstanceState数据");
                SharedPreferences sharedPreferences = getSharedPreferences("save", MODE_PRIVATE);
                SharedPreferences.Editor editor = sharedPreferences.edit();//获取编辑器
                editor.putString("key", "我是重启前的SharedPreferences数据");
                editor.commit();//提交修改
            }
            super.onSaveInstanceState(outState, outPersistentState);
        }
    
    
    

    首先来看执行效果,当打开activity时,log如下所示


    开启activity log

    如源码所示,先执行带有PersistableBundle的onCreate后执行 onCreate(Bundle savedInstanceState)
    此时我们重新启动


    重启设备log

    当手机黑屏的瞬间执行了这些
    当我们重启手机完成后,发现没有获取到我们想要的
    “我是重启前的onSaveInstanceState数据”

    重启后重新打开App log

    然后看官方对persistableMode的解释


    官方解释

    由于我的activity设置了android.intent.action.MAIN,也就保证了我的activity在task中处于root下,在此activity上也没有任何activity,所以官方说的following a reboot,that PersistableBundle will be provided back to activity in its onCreate() method
    并没有真正意义的实现,可能是我实现时哪里出了差错,求大神指定迷津

    到这里,对于activity的onCreate差不多把自己的理解记录的七七八八,最后总结下。

    1、Activity生命的七个周期首先执行onCreate
    2、5.0以后的API会有两个onCreate方法,若不设置persistableMode,只会回调onCreate(@Nullable Bundle savedInstanceState),若设置persistableMode,则两个onCreate都会回调
    3、将persistableMode设置为persistAcrossReboots,重启设备时回回调onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) 方法,但是重新打开app时拿不到outPersistentState的里的值(待确定),但是可以通过自己储存数据的方式防止设备重启数据消失的问题

    相关文章

      网友评论

          本文标题:小记Activity生命周期(onCreate)

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