您的位置:首页 > 移动开发 > Android开发

“哎哟!蛮吊的” 之 Android Activity生命周期

2015-07-27 14:20 519 查看
本篇博客是本菜鸟为大家提供的一个调养生息的吐纳功法,如果连呼吸都不顺畅了,还练个毛线的武功哟!屁话不多说,直接开练:

首先我想说明关于activity的三个特征:

1:activity有5个运行状态:创建,运行,暂停,停止,销毁。(对于activity的5个运行状态,等你首次阅读完本博客静下来想一想就明白了,本人语言能力有线,请多谅解!)

2:activity有三个作用明显的生命周期:单独的完整生命周期,屏幕的显示生命周期,应用的交互生命周期。

3:当前activity切换到其他activity的时候(无论是启动,还是回退),并非是当前activity生命周期完全结束后才启动的其它activity,而是另有隐情!

当然,下面也会讲到home键和back键的区别,以及相互实现对方的功能。。。

还有我们先看activity生命周期的基本周期方法:



接下来我运行一次程序,大家看真相:



这个图说明了启动activity首先他会调用oncreate(),onstart(),onresume()三个方法,然后,我点击back按钮退出程序,再看真相:



没错,它调用了三个方法。这说明如果activity准备back返回到之前的界面的时候(当然,这里没有其他界面,自然返回到主界面),那么就会调用这onpause(),onstop(),ondestroy()这三个方法,哈哈!(其实这就是“单独的完整生命期”)。

“单独的完整生命周期”应该是:oncreate(),onstart(),onresume(),onpause(),onstop(),ondestroy();

但是呢?这里还是有需要注意的地方哈!这种情况其实只会出现在activity和主界面之间通过back键的切换,以及activity和activity之间在完全覆盖界面的条件下切换时,才会发生这种情况。为毛我会这么说呢?因为在activity里面,我们能够通过函数setTheme(android.R.style.Theme_Dialog)设置activity以窗口模式弹出,这个时候,切换的activity就不会完全覆盖之前的activity,那么情况就不一样了!连带的,如果在同一个activity里面让一个activity以窗口的形式弹出和弹出一个真正的dialog(一个真正的窗口),又有什么区别呢?接下来我们慢慢讲解:

此时,我把之前的代码在新起的activity里面粘贴了一次,接下来就把之前的activity叫做A,现在新起的叫做B,这样搞我方便些哈。

在A里面启动B,我们来看真相:



现在开始,这里会混杂着讲解 --> 屏幕的显示生命周期以及之前提及的特征第3点:“当前activity切换到其他activity的时候(无论是启动,还是回退),并非是当前activity生命周期完全结束后才启动的其它activity,而是另有隐情!”一起讲解:

首先,大家看上面的真相,有“-”符号的代表是activityB,通过真相我们可以知道当启动别的activity的时候并不是先完全的结束A,然后启动B。而是先把A通过其onpause()函数“暂停”掉,然后马上启动B,等B启动完毕之后,再回过来“停止”A,注意这里暂停和停止的区别哈。

此时B完全的遮挡和代替了A,也就是我们在界面上是看不见A了,看见的都是B,接下来,我点击back键,让B切换到A。请看真相:



同理可得:界面由B返回了A,过程是先“暂停”了B,然后启动A,等到A完全的运行之后,再“停止“了B,并且完全的销毁了B。或许在这里有人会问为什么A跳转B的时候没有销毁A呢?其实这是android内置机制决定的,android内置机制有一个专门记录activity的堆栈,正是因为这个,所以在你后退界面的时候,android才能知道应该回退到那个界面,你说是吧?这里对这个就不先讨论了哈。接着上面说,那么现在你就应该知道一个结论了:

“当activity界面切换的时候(无论跳转还是回退),都是先暂停当前页面,启动并正常运行跳转页面,等到跳转页面正常运行后,再决定暂停页面是否停止以及是否销毁。” 那么关于我们讨论activity的第三个特征就先结束了哈。

接下来我们再仔细想想刚刚当我们从B跳转到A的时候,A是从不可见到可见的变化。那么第二个生命周期“屏幕的显示生命周期”也跟到出来了,根据真相我们不难看出它的作用域是这样的:通过调用A的onrestart(),onstart(),onresume()让A达到完全运行的状态。和最开始不同的是,因为之前A是创建了的,跳转到B只是停止了A,但是并未销毁A,所以当我们回退的时候,系统会启用之前的A,所以就可以在不用执行oncreate()函数就可以让A达到完全运行的状态。当然,“屏幕的显示生命周期”的作用域并非如此,再结合A跳转B的效果图,我们可以想到A还启动用了onpause(),onstop()方法,综上所述:

“屏幕的显示生命周期”完整的表达是:onstart(),onresume(),onpause(),onstop()。

或许这里也有人问,为毛onrestart()不在这里面,对于这个问题,我的理解是,当首次启动页面显示的时候,并没有调用onrestart()函数,那就说明它并未包含在“屏幕的显示生命周期”中,如果非要说明什么,我觉得也只能说明切换的当前页面是在被其他页面“完全遮挡”的情况下“回退”并显示出来的。至此,“屏幕的显示生命周期”讲解搞定,接下来我们再看“应用的交互生命周期”。

这里呢!我们不光要讲解“应用的交互生命周期”,还要混杂着activity以窗口模式弹出,以及弹出真正的窗口(dialog)对actvity生命周期的不同影响一起讲解:现在我把B改成了以窗口模式弹出,我再运行程序,让A跳转到B,大家看真相:



和之前从A跳转到B的区别不知道大家看清楚没有?之前A跳B的时候A是调用了A的onstop()方法的,而这里并没有,因为真相上就没有”55555555555555555555555“的存在!!!所以,一个activity是否以窗口模式弹出(或者说是否完全遮挡之前的activity)的影响之一是:之前的activity是否会调用onstop()方法来“停止”自己。

然后我们再关闭B返回A,再看真相:



此时在真相中不难看出从B到A,只是调用A的onresume()方法,并未像之前还调用了onrestart()以及onstart()方法。所以,综上所述:如果activity以窗口模式弹出,那么在它之前的activity在进行activity切换的时候,将不会调用onstop(),onrestart(),onstart()方法。

那么如果我们在activity里面弹出dialog对activity生命周期的影响是什么呢?会和activity以窗口模式弹出的影响一样吗?接下来我们在A里面弹出一个弹出框(dialog)并关闭,我们看真相:



A相当淡定,除了表明其正在运行意外,其他的什么都没有。所以,根据真相我们也可以得出结论,如果在activity里面弹出dialog,对activity生命周期完全没有影响。

最后,我们还是总结性的得出3个小结论:

1:activity和activity发生界面切换的时候,如果切换的界面能够完全遮挡之前的界面,那么暂停之前的activity之后还会调用它的onstop方法。

2:activity和activity发生界面切换的时候,如果切换的界面不能够完全遮挡之前的界面,那么暂停之前的activity之后不会调用它的onstop方法,只会调用其onpause方法。

3:如果在activity里面弹出dialog,dialog的弹出对activity的生命周期是完全没有影响的。

接下来并没有玩完,不知道大家有没有想起,我们说好讨论的“应用的交互生命周期”并没有讲呢?其实,我已经讲解出来了,只是大家没有去细想而已,接下来继续弄呗,大家现在继续仔细想想,当我们把B设定为窗口模式弹出的时候,此时我们是无法立即点击原本属于A的地方的,只有等到B消失后,才能点击A,哈哈!这就是问题所在,我们从A启动B,B返回A的这整个流程加上相应的“真相”可以明白:A从不能点击到可以点击,A调用了onpause(),onresume()两个方法,所以,这里也可以得出结论了:

完整“应用的交互生命周期”应该是:onresume()开始,onpause()结束。

自此,关于activity的5个(运行状态),3个(生命周期),3个(界面切换是否完全覆盖的分别影响), 2个(界面切换的顺序)-------->>>>>>>>讲解完毕,接下来讲解back和home的区别和相互实现。

关于back键和home键,我这里只做简单介绍了哈,毕竟篇幅太大了就啰嗦了,这个也不难,只需要动下脑袋就搞定了哈:

1:back键是回退,它会消除activity堆栈中当前activity的记录。所以当你回退一个界面的时候,除非你指定跳转到之前的页面,否则没有办法通过原系统记录跳转到之前的页面。

2:home键看起和back键一样,因为他们在首次进入应用的时候都能点击一下就退到主界面。但是,他们实现的原理根本不一样,home键是跳转到主界面,而back是回退到主界面。其中的跳转和回退希望读者自己斟酌!

3:监听home键通过dispatchKeyEvent(KeyEvent event)实现,监听back通过onBackPressed()实现。

4:back键如果想实现home键的功能:那么只需要在onBackPressed()方法里面调用moveTaskToBack(true)方法,其中的参数意义:参数为false时,仅当应用中activity堆栈里面只有一个activity时,点击back键和home键效果一样。参数如果为true时,点击back键始终和home键效果一样。

自此,home键和back键简单讲解完毕。

这里还想提及一个点,感觉比较有意思。就是关于在android手机里面设置“不保留活口”这个点,我知道的也不多哈:

当我们进行页面跳转的时候,不管是否完全覆盖,都会把之前activity的生命周期方法全部运行一次(oncreate(),onstart(),onresume(),onpause(),onstop(),ondestroy()),但是,它并没有消除activity堆栈中的记录,因此一样可以返回,但是整个生命周期将发生变化,至于变化在哪里,这里就不讲解了,你们可以自己去瞅瞅就明白了!不要给我说没有用?等你们以后遇到进入二级界面的时候,应用莫名其妙闪退的时候,你就知道它的威力了!哈哈。

不好意思,还遗留了一个问题,或许会有人问:“如果activity不是通过startActivities(intents)启动!而是通过startActivityForResult(intent, requestCode)启动,那对activity生命周期的影响有那些?”关于这一点呢!我可以直接告诉大家,没有影响。顶多就只是在返回界面的时候优先调用一下onActivityResult(int requestCode, int resultCode,
Intent data)

这个方法,然后代码走的依然是原来那个流程。

因为本人也是菜鸟,所以知道的也不多,如果谁知道的比较多,或则有什么问题,可以相互探讨或则留言哈!

如果大家觉得大兄弟写的还可以就给个赞呗!呵呵,求赞哈!
如有转载,请贴上原博客的地址:http://blog.csdn.net/garlic_you_ruthless/article/details/47084441,谢谢!

最后,还是放声长笑一下吧!“哇哈哈,总算特么的写完了,嘎嘎~~~”;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: