继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Android,四大组件之Activity

小罗希冀
关注TA
已关注
手记 2
粉丝 3
获赞 104
Activity的生命周期

Activity中定义的7个回调方法覆盖了一个正常的Activity的从创建到销毁的每个阶段(这些方法均不需要手动调用,系统会自动回调)

onCreate():在Activity第一次被创建时使用该方法,在该方法中主要是完成Activity的初始化操作,例如加载布局,获取控件实例以及绑定事件监听器等等。

onStart():当Activity由不可见变为可见时,回调该方法,但此时的Activity还不能与用户进行交互。

onResume():当Activity完全可见并且能够与用户进行交互的时候,回调该方法。

onPause(}:当Activity被其他Activity遮挡,无法与用户进行交互时回调该方法,但此时的Activity还是处于可见状态(不一定是完全可见)的。

onStop():当Activity被其他Activity遮挡而导致完全不可见的时候,回调该方法。

onDestory():销毁Activity之前回调该方法。

onRestart():在Activity由暂停状态变为运行状态之前回调该方法。

一个Activity正常情况下从启动到销毁的方法回调顺序

从系统开始创建Activity到Activity能获取用户焦点(可见并且具有与用户进行交互的能力)的时候,Activity的方法回调,如下图:
图片描述

当用户按下返回按钮,或者按下Home键的时候,Activity方法回调的顺序,如下图:
图片描述

Activity之间进行跳转的方法回调顺序

从MainActivity跳转到SecondActivity两个Activity的生命周期方法回调的顺序,如下图(注意观察黄色标识区域):
图片描述
从上图可以知道,MainActivity跳转到SecondActivity的过程中,首先会调用MainActivity的onPause()方法,然后紧接着就是依次调用SecondActivity的onCreate()、onStart()、onResume()方法,最后才是调用MainActivity的onStop()方法。

然后我们再来看看从SecondActivity返回到MainActivity的生命周期方法回调的顺序,如下图(注意黄色部分标识的区域):
图片描述
根据上图我们也可以知道,SecondActivity返回到MainActivity的过程中,同样也是先调用SecondActivity的onPause()方法,紧接着就会依次调用MainActivity的onCreate()、onStart()、onResume()方法,最后才调用SecondActivity的onStop()、onDestory()方法。

根据这两个Activity相互跳转时生命周期方法回调的顺序我们得出这样一个规律,启动一个新的(或者已存在的)Activity时,首先会回调旧的Activity的onPause()方法,然后就会依次回调新的(或者已存在的)Activity的onCreate()、onStart()、onResume()方法,最后才是调用就Activity的onStop()方法。系统采用这样的回调顺序是为了缩短Activity跳转的时间间隔,同时我们也可以根据Activity的回调顺序可以意识到在Activity的onPause()方法和onStop方法中不要进行耗时操作并且为了进一步缩短Activity跳转的时间间隔,我们可以选择尽可能地减少在onPause()方法的代码,把更多的代码放在onStop()方法中执行,这样子我们就可以进一步减短不同Activity之间跳转时间间隔。

两个特别的方法,onSaveInstanceState()和onRestoreInstanceState()

可能有细心的小伙伴会发现在上一点中,从MainActivity跳转到SecondActivity过程的图片中出现了一个陌生的方法叫做onSaveInstanceState(),这个方法在onStop()方法之前回调。但是在SecondActivity返回MainActivity的时候,SecondActivity并不会调用onSaveInstanceState()方法,这是为什么呢?

因为在Activity发生意外情况(例如手机内存不足,用户直接按Home键)或者Activity由运行状态进入暂停状态或者停止状态的时候,就会触发onSaveInstanceState()方法对Activity的临时数据进行保存。这也就解释了为什么在MainActivity跳转到SecondActivity时会触发onSaveInstanceState()方法了,因为MainActivity从运行状态变成停止状态了。而为什么在SecondActivity返回MainActivity是SecondActivity并不会调用onSaveInstanceState()方法呢?原因是用户是通过按下返回键来回到MainActivity,也就是主动返回,此时系统会认为这个Activity的临时数据是不需要存储的,所以也就不会调用该方法。

onRestoreInstanceState()方法这是负责将存储起来的临时数据在同一个Activity中进行恢复。并且有一点要注意的是,实现回调该方法的条件是,该方法的Activity的确被销毁了,这样子才会有恢复临时数据的必要。这也是为什么在SecondActivity返回到MainActivity的时候,并没有回调MainActivity的onRestoreInstanceState()方法。
接下来我们来看看这两个方法的代码,代码如下:

@Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Log.d("MainActivity","MainActivity onSaveInstanceState()");
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        Log.d("MainActivity","MainActivity onRestoreInstanceState()");
    }

从上面两个方法的代码可以看出,保存以及恢复临时的数据都是来自于一个Bundle对象的,Bundle对象提供一系列的put和get方法来存储或者取出各种类型的数据,所以这两个方法执行的主要思想就是,在onSaveInstanceState()方法中通过调用Bundle对象的一系列put方法存储各种类型数据,比如int,char,String等等,然后在onRestoreInstanceState()方法中通过对Bundle对象的一系列get方法获取存储起来的数据,就是通过这种思想实现对Activity的临时数据存储以及恢复的目标。

可能看到这里,记忆力比较好的小伙伴会发现,onCreate()方法的参数跟onRestoreInstanceState()方法的参数是一毛一样的,那么是不是也可以在onCreate()方法中恢复临时数据呢?答案肯定是可以的啦。通常在onCreate()方法中恢复的临时数据都是自己在onSaveInstanceState()中通过对Bundle对象的一系列put方法主动保存的数据,并且在Activity没有销毁的情况下(也就是系统不会回调该Activity的onRestoreInstanceState()方法)只能通过onCreate()方法进行恢复数据了,比如我在一个Activity中的EditText中写入了一段话,然后跳转到别的Activity后再返回来,很显然系统并不会自动回调onRestoreInstanceState()方法,所以只能通过onCreate方法来恢复临时数据。当然某些情况下onSaveInstanceState()和onRestoreInstanceState()方法都会被系统调用,比如旋转屏幕,Activity会先销毁,再创建,如下图所示:
图片描述

关于这两个方法还要注意一点:onSaveInstanceState()和onRestoreInstanceState()方法都不是Activity生命周期的回调方法呦,因为他们并不一定会被回调。

Activity的管理方式

通常情况下,一个应用程序的Activity有很多,那么这么多的Activity,系统是以什么样的方式对Activity进行管理呢?其实系统通过栈的方式来管理应用程序的Activity。栈具有“先进后出”的特点,只有处于栈顶的Activity才会获取用户的焦点,与用户进行交互。那么可能我们会有一点疑惑,启动一个已经存在的Activity是创建一个这个Activity的新的实例还是将不处于栈顶的Activity移动到栈顶呢?其实这就涉及到了Activity的启动方式,请看下一点...

Activity的启动模式

通过在AndroidManifest.xml文件中设置<activity>标签的launchMode属性可以设置Activity的启动模式,有如下4种可选

(1)standard:这是Activity的默认启动模式,系统启动该Activity时是直接创建新的Activity实例,而不管在Activity栈中是否存在该Activity实例。

(2)singleTop:在该模式下启动Activity时,会检测Activity栈栈顶的Activity实例是否为将要启动的Activity,如果是,则不创建新的实例

(3)singleTask:在该模式下启动Activity是,会检测整个Activity栈是否存在该Activity实例,如果存在,则把该Activity实例移至栈顶,不创建新的实例

(4)singleInstance:在该模式下启动的Activity,系统会创建一个新的Activity栈去存储这个新建的Activity实例,这种模式下启动的Activity的好处是能让多个应用程序共享同一个Activity,例如支付宝的快捷支付功能。

以上的这些内容是我学习Activity组件的一些小小的总结,如果有小伙伴认为有不对的地方,欢迎指出。让我们相互学习,一起努力吧。
打开App,阅读手记
5人推荐
发表评论
随时随地看视频慕课网APP