小记Activity生命周期(onCreate)
干了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 to
persistAcrossReboots
.
*@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里重写了如下代码
@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数据”
然后看官方对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的里的值(待确定),但是可以通过自己储存数据的方式防止设备重启数据消失的问题
更多相关文章
- unity和Android之间互相调用
- Android(安卓)Service更新UI的方法之AIDL
- android桌面小部件appwidget使用ListView或者StackView如何刷新
- android sharedpreference保存boolean,int,float,long,String和图片
- 《Android开发艺术探索》笔记(五)
- androidP 系统集成时发现部分应用初次打开时提示此应用专为低版
- Android之AlertDialog的基础使用
- 【Android】网络通讯
- Android(安卓)native CursorWindow数据保存原理