干了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里重写了如下代码

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

更多相关文章

  1. unity和Android之间互相调用
  2. Android(安卓)Service更新UI的方法之AIDL
  3. android桌面小部件appwidget使用ListView或者StackView如何刷新
  4. android sharedpreference保存boolean,int,float,long,String和图片
  5. 《Android开发艺术探索》笔记(五)
  6. androidP 系统集成时发现部分应用初次打开时提示此应用专为低版
  7. Android之AlertDialog的基础使用
  8. 【Android】网络通讯
  9. Android(安卓)native CursorWindow数据保存原理

随机推荐

  1. 读取raw文件下文件内容
  2. android开发--RelativeLayout用到的一些
  3. Android(安卓)ImageSpan与TextView中的te
  4. Android中WebView如何加载JavaScript脚本
  5. Android预制APP第一次打开时不弹权限提示
  6. AndroidのUI布局之layout weight
  7. android-GooglePlay安装来源追踪PlayInst
  8. Android(安卓)更新UI的两种方法——handl
  9. android 设置时区
  10. Android的XMPP协议的smack开源框架