通过返回栈的活动来理解Activity生命周期

Android中最常用的无非就是Activity,
而精通其中的原理和生命周期也是一个Android程序员必备的技能,包括在面试的时候很多问题都会涉及到activity生命周期。

当我们启动一个app的时候,其实就已经开始了activity的生命,
而这一开始的activity就是MainActivity,基本在我们创建应用的时候就存在了。

下面一张图来帮助我们了解生命周期。

图片来源网络

Activity中一共有七大生命周期,来控制整个应用的活动,

从onCreate()开始
到onDestory()结束
已经用掉了两条命

真正需要我们折腾的是剩下的5条命。

关于返回栈(Task),在《第一行代码Android第二版》书中解释是

其实Android是使用任务(Task)来管理活动的,一个任务就是一组存放在栈里活动的集合,这个栈也被称为返回栈(Back Stack)。

通俗的理解就是说,每一次启动一个新的Activity,然后这个启动的活动就被存放在返回栈中,并且处于栈顶的位置。这个过程称为入栈。

反之当一个活动结束-Activity被销毁(finsh())的时候,或者按下了返回键(back)那么这个活动的activity就会被当做垃圾清理出去。这个过程称为出栈

因为返回栈是一个集合,用数组的形式存放Activity活动的,所以在启动Activity的时候,数组中就会在栈顶增加一个活动,而之前处于栈顶的活动自动给新来的让位。所以我们总是能看到最新的界面。

图片来源网络

Activity生命周期

当我们打开一个Activity的时候会执行生命周期中的onCreate()、onState()、onResume()这三个方法,

onCreate()用于加载布局,加载数据,实例化控件、监听,等。返回栈收到请求加入指令。
onState()将开启活动,由于布局,数据是不可见,静态的,当启动该方法时,将其变为可见,活动的。也可以理解为活动通过指令,开始存放到返回栈中。
onResume()加载完成静态时执行的活动,这时候活动已处于栈顶。并且用户可见,可操作控件,就像一个出列等待命令的将士。

接着要进行下一步,打开另一个Activity,那么之前的Activity还需要继续走完他的生命周期,于是又开始执行:

onPause()到这里收到准备撤的命令,但是还没行动,此时活动依然处于栈顶的位置。页面处于可见状态。

但是这时候突然士兵想去wc怎么办,或者行李没带?吃一碗他媳妇给他送行的面?。这时候就要返回一下,比如弹个窗口,上面挂着吃饭的牌子,吃完后再进入待命状态,那么这期间的一个小动作就执行了

onResume()利用交互改变状态。
onPause()

这时候的士兵可能就是一个吃饱饭,或者饿着肚子的,都有可能,然后依然是等候命令,可能没有饭吃了,于是:

onStop()撤退,页面已经被新的Activity覆盖,新的Activity占据了栈顶。原Activity不可见。活动停止

你以为这就结束了?当然没有,君子报仇十年不晚,无论新的Activity如何折腾,只要他按下的返回键(back),或者调用了finish(),就会又执行:

onRestart()重启活动
onStart()
onResume()

但是如果新的Activity刚获得栈顶的位置,又被第三个Activity加入,那么刚开始的Activity就失去了返回(finish()/back)的机会,所以只能结束自己的生命:

onDestory()终止活动。

我们在开发时,用的最多的就是onCreate,初始化数据。
然后是onResume,刷新数据。
有些网络请求的数据就是在onResume方法执行,因为有可能在我们没有销毁前一个Activity的时候,之前的Activity数据集发生变化,返回直接执行onState,因为该方法只是用来转换静态数据的,而onResume是用来处理交互的。
所以需要在这里刷新数据。

在我们手机上开发者模式中有个保留活动的选项,默认是选中的,如果不保留的话那么在按手机Home键的话,活动就会被销毁也就是执行onDestory,否则是一直停在onStop状态。

有时候我们会发现Home之后再打开的话app重启了,这是因为内存不足,有些手机系统自动帮我们终结掉了无用的活动。

onSaveInstanceState
最后提一下这个方法,可能在我们开发时用的少,在stop方法里左边有个直接返回到onCreate方法里的活动。
指的是进程被杀死的情况,有可能是处于后台运行时被杀死,再进来就会重新执行onCreate,过程中会产生该方法。

从字面很容易理解,就是保存实例。因为当活动被杀死后,页面修改过的内容就会丢失,比如一些设置还没保存,修改信息未提交这种。
那么利用onSaveInstanceState就可以保存临时数据。

使用方法:

   @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString("key","value");
    }
......


 @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.httptest);
        savedInstanceState.getString("key");


    }

BUG

1、
如果我们在onResume进行网络数据请求的话,可能出现一个冲突,在进去Activity的时候,我们设置的默认布局会优先加载,如果网络差的话,网络数据一直加载不出来,所显示的就是默认我们后台写死的布局。

如果涉及到相关操作需要网络加载完成操作的可以提前把按钮设置为隐藏、或者设置gone,还可以设置加载中效果,推荐设置加载等待效果。

2、
Fragment生命周期是依赖于Activity生命周期的,比如MainActivity下有四个Fragment,当Fragment里面的Activity活动发生变化可以直接影响到整个MainActivity,当然也包括四个Fragment。

所以当我们在操作Fragment里面的Activity活动的时候,要注意在返回的时候通知Fragment里的数据更新,或者是把数据请求的方法直接在Fragment的onResume方法里实现。


END
由于本来对生命周期的了解都不够全面,加之最近项目中遇到的一些小毛病,也是跟生命周期相关,所以就参考了一些资料,以个人的思路做了理解。
有不足的地方还望多指出!

参考资料:
《第一行代码》
Android任务和返回栈完全解析,细数那些你所不知道的细节

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值