Android开发中Activity的生命周期及加载模式详解
本文给大家介绍activity的生命周期,如果大家学习过ios的小伙伴的话,activity的生命周期和ios中viewcontroller的生命周期非常类似。生命周期,并不难理解。一个人的生命周期莫过于生老病死,花儿的生命周期就是花开花谢了。在android中activity的生命周期莫过于activity的创建到消亡的过程了。本篇博客就会介绍activity生命周期中的不同阶段,通过实例的形式来窥探一下activity的生命周期。搞明白activity的生命周期是至关重要的,因为只有搞明白每个生命周期的每个阶段,你才能在不同段做不同的事情。
接下来我们将通过一个实例来介绍activity的生命周期,在这个demo中会有一个mainactivity, mainactivity就是app启动后第一个显示的activity。在mainactivity上有一个按钮,点击这个按钮就会跳转到secondactivity,点击返回键就会从secondactivity中返回到mainactivity中,再点击返回键就会退出app。通过这一些列的activity的切换,我们将通过打印log的方式来进行观察activity的生命周期。
一.代码编写
其实这篇博客的代码是非常简单的,就是重写activity生命周期不同阶段的方法,然后在方法中进行log的打印,从而来标记这个生命周期的阶段。而demo的ui也是灰常的简单的,所以activity的layout文件就不做过多的赘述了。接下来看一下两个activity中的关键代码。
1.下方的代码是mainactivity中的关键代码,对activity生命周期的不同阶段进行重写,然后打印日志,标记出是哪个activity中的哪个方法。在oncreate()方法中通过id获取button, 然后给按钮绑定上单击事件,点击button时跳转到secondactivity中。具体代码如下。
@override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); log.d("lifecycle", "mainactivity: 我是oncreate方法,我会在activity第一次被创建是调用"); button jumpbutton = (button) findviewbyid(r.id.jump_second_button); jumpbutton.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { //跳转到secondactivity intent intent = new intent(mainactivity.this, secondactivity.class); startactivity(intent); } }); } //ctrl + o 选择父类中的方法进行重写 @override protected void onstart() { super.onstart(); log.d("lifecycle", "mainactivity: 我是onstart方法,我会在activity由不可见变为可见时调用"); } @override protected void onresume() { super.onresume(); log.d("lifecycle", "mainactivity: 我是onresume方法,我在activity处于运行状态时调用"); } @override protected void onpause() { super.onpause(); log.d("lifecycle", "mainactivity: 我是onpause方法,我会在activity暂停时调用"); } @override protected void onstop() { super.onstop(); log.d("lifecycle", "mainactivity: 我是onstop方法,我会在activity停止时调用"); } @override protected void onrestart() { super.onrestart(); log.d("lifecycle", "mainactivity: 我是onrestart方法,我会在activty从停止状态变为运行状态时调用"); } @override protected void ondestroy() { super.ondestroy(); log.d("lifecycle", "mainactivity: 我是ondestroy方法,我会在activty销毁之前调用"); }
2.在secondactivity中的也是重写上述方法,唯一的区别就是把上面日志中的mainactivity改成secondactivity,代码类似就不往上粘贴了。
二、运行观察打印的log
运行我们的app,然后观察打印的日志,通过实例来分析activity的生命周期。具体步骤如下:
1.创建并激活activity
首次打开app所打印的log如下图所示。打开app首先看到的时mainactivity, 通过log我们不难看出在mainactiviy首次出现时要调用如下三个方法,经过下方的三个方法,mainactivty就会被创建,然后变为可见,最后处于运行状态。
(1).oncreate()方法:activity首次出现创建时会调用该方法,在之前的demo中我们在此方法中加载activity的布局和或控件并关联事件。
(2).onstar()t方法:接着就会执行onstart()方法,activity由不可见状态变为可见状态会调用该方法。
(3).onresume方法:activity变为可见后接着要调用onresume方法来变为运行状态。
2.activity间切换
为了更清楚,在点击按钮跳转到secondactivity之前,我们可以清除一下log, 下方左边有一个垃圾桶的标志,就是用来清除之前打印的日志的。下方所打印的日志就是点击跳转按钮时所打印的日志。在这个切换过程中,mianactivty会停止运行变为不可见,而secondactivy就会被创建并且处于运行状态。具体步骤如下。
(1).onpause()方法:当点击跳转按钮时,运行中mainactivity就会调用onpause()变为停止状态,但仍然可见。
(2).接着就是secondactivity调用oncreate()方法进行创建,调用onstart()方法进行显示,调用onresume()方法进行运行的过程。
(3).onstop()方法:当secondactivity处于运行状态时,mainactivity就完全不可见了,所以就会调用onstop()方法,进入完全不可见停止状态。
3.从另一个activity返回
从secondactivity中点击返回键,从secondactivity中返回到mainactivity中。下方的log是点击返回按钮时所打印的log.
(1)onpause()方法:点击返回按钮后,secondactivity会调用onpause()方法,进入暂停运行状态。
(2)onrestart()方法:接着mainactivity就会调用onrestart()方法,由停止状态变为运行状态。然后mainactivity又会调用onstart方法从不可见变为可见,接着会调用onresume()方法最终进入运行状态。
(3)当返回到mainactivity中并且mainactivity处于运行状态后,secondactivity会调用onstop方法,停止运行并不可见。因为secondactivty做的事出栈操作,停止运行后,就会调用ondestory方法进行销毁。下此在进入secondactivity中时,还是从oncreate方法进行执行。
4.activity退出并销毁
接着在mainactivity中点击返回按钮就会退出app了,下方是退出app时打印的log信息。mainactivty先调用onpause()方法变为暂停运行状态,然后再调用onstop()方法停止运行,最后调用ondestroy()方法进行销毁。
三.生命周期流程图
1.上面是用语言通过实例打印出的log来描述两个activity切换的生命周期,接下来将用一个流程图来描述这一过程,具体流程图如下。
2.通过上面的实例不难分析出一个activity的生命周期分为哪些阶段,并且很容易的看出哪些阶段在什么时候执行,所以我们很容易的画出一个activity的生命周期,下方的流程图是一个activity的生命周期。
四.activity的加载模式
activity的启用模式也较为简单,它会在活动切换时用到。activity的启动模式分为四种,standard、singletop、singletask、singleinstance模式。接下来将为大家详细的介绍一下这几种加载模式。
activity的加载模式可以在配置文件androidmanifest.xml中进行配置,配置项为android:launchmode具体如下图所示:
1.standard模式
在activity的栈中无论该活动有没有加入栈,活动就会被创建。测试方式是把mainactivity的launchmode设置成standard, 在mainactivity中添加一个按钮,点击按钮使用intent跳转到当前activity,看oncreate方法中打印的log。点击按钮的方法如下:
button launchmodelbutton = (button) findviewbyid(r.id.launch_model_button); launchmodelbutton.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { intent intent = new intent(mainactivity.this, mainactivity.class); startactivity(intent); } });
standard加载模式的栈如下所示,无论栈中有没有该对象的实例,都会被创建。
2.singletop模式
只要被创建的活动不位于栈的顶部,该活动就会被创建入栈。如果将要被创建的活动位于栈的顶部,该活动的实例就不会被创建。测试方法,把上面的模式直接改成singletop模式,mainactivty往自己身上跳转就不会从新创建一个新的实例,会重用之前在栈顶中的实例。如果是mainactivty跳转到secondactivty, 然后secondactivity再次跳转到mainactivty, 那么此时的mainactivity将会被创建,因为栈顶是secondactivity。如下所示:
3.singletask模式
单任务模式,这个也不难理解,如果从mainactivty跳转到secondactivity, 如果再从secondactivty跳转到mainactivity, 在单任务模式下mainactivity已经在栈中,就会把它之前的activity出栈,使其处于在栈顶活跃的位置。原理如下图所示:
4.singleinstance
可以看成单例模式,这个比较特殊,被设置成singleinstance的activity将会放入另一个栈中,因为这样为了便于共用。上面3中模式位于同一个栈中。下方thirdactivity跳转到一个加载模式为singleinstance的activity中。
今天的activity生命周期就先到这儿,相关内容会在下篇博客中进行更新。