小记Activity生命周期(onCreate)

2017-11-15  本文已影响0人  bridegg

干了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的里的值(待确定),但是可以通过自己储存数据的方式防止设备重启数据消失的问题
上一篇下一篇

猜你喜欢

热点阅读