Android开发进阶学习整理--Activity篇

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/reakingf/article/details/51793434

一、生命周期:

首先给个Activity生命周期官方图,如下。



1. Activity第一次启动时,回调如下:onCreate->onStart->onResume


2. 当用户打开新Activity或切换到桌面时:onPause->onStop,但当新Activity采用透明主题或非全屏(如设置Dialog主题时,当前Activity不会调用onStop;


3. 当用户再次回到原Activity时:onRestart->onStart->onResume;


4. 无论是从当前Activity A切换到Activity B还是finish掉当前Activity A回到ActivityB,都会先调用Activity A的onPause方法,再调用Activity B的onResume方法,即总是先调用当前Activity的onPause才会启动新的Activity,启动完再调用原ActivityA的onStop方法,如下图。





5. 由4可知,为了使新Activity尽快显示出来并切换至前台,我们不能在onPause中执行重量级的操作,因为必须onPause执行完新Activity才能Resume.


6. Activity意外退出,应在onPause中保存用户数据,因为onStop和onDestory不一定会被调用。


7. 资源相关的系统配置发生改变导致Activity被杀死并重新创建,默认情况下Activity的处理情况如图:



即关闭并重启该Activity。其中,onRestoreInstanceState只有在Activity异常终止后重新启动时,才会被系统调用;onSaveInstanceState除了在异常终止的情况下,当用户按Home键或启动新Activity都会触发系统对该方法的调用,下图便是按下Home键或启动新ActivityB时的ActivityA的生命周期。(注意,这里说的onSaveInstanceState和onRestoreInstanceState指的是onSaveInstanceState(Bundle outState)和onRestoreInstanceState(Bundle saveInstanceState),而不是onSaveInstanceState(Bundle outState,PersistableBundle outPersistentState) 或 onRestoreInstanceState(Bundle saveInstanceState,PersistableBundle persistentState)



按下Home键后ActivityA的生命周期变化情况



启动新ActivityB时ActivityA的生命周期变化情况


讲了这么多,onSaveInstanceState什么呢?它其实是用来保存当前Activity状态的,且调用时机在onStop之前,但和onPause没有既定的时序关系,即可能在onPasue之前也可能在onPause之后调用(不过本人尝试了很多遍都是在onPause之后才调用)。重建后会在onStart之前调用onRestoreInstanceState来获取onSaveInstanceState保存的Bundle对象,用于数据恢复。这两个方法还会帮我们自动保存并回复当前Activity的视图结构,如文本框中用户输入的信息,流程为:意外发生 --> Activity 调用 onSaveInstanceState 保存数据 --> Activity委托Window保存数据 --> Window委托它上面的顶层容器(一个ViewGroup,一般为DecorView--关于Android的view结构和事件处理可参考Android视图架构及事件分发处理机制)保存数据 --> 顶层容器通知其所有子元素保存数据。恢复也类似。

         当然,除了在onRestoreInstanceState中恢复外,也可以自己在onCreate中恢复,但onRestoreInstanceState一旦被调用其Bundle参数saveInstanceState一定有值,而onCreate则需要判断saveInstanceState是否为空,因为正常启动时为空,所以需要判断。官方文档建议采用onRestoreInstanceState恢复数据。


8. 资源内存不足时导致低优先级的Activity被杀死的处理情况和7种的一样,其中优先级:前台Activity>可见但非前台Activity>后台Activity。


9. 系统配置改变时Activity的生命周期分3中情况,第一种就是7中的那种,重启Activity,重新调用各个生命周期,其中切横屏时会执行一次,切竖屏时会执行两次;第二种即在AndroidMenifest.xml中指定Activity的configChanges属性,其中设置为android:configChanges=”orientation”时切横竖屏各执行一次,设置为android:

configChanges=”orientation|keyboardHidden”时都不会重新调用生命周期,只会调用onConfigurationChanged方法。


二、启动模式

Android中,每次启动一个Activity,系统都会将其实例放入任务栈中,当Activity被finish时其实例便从栈中删除。当任务栈中没有Activity时系统便回收该任务栈。


1. standard:标准模式,也是系统默认的模式。每次启动一个新的Activity都会创建一个新的实例,不管该实例是否已经存在于任务栈中。一个任务栈可以有多个实例,一个实例也可以属于多个栈。谁启动了该Activity,该Activity就运行于启动它的Activity所在的栈中。但是,如果用ApplicationContext去启动Activity时会报错,因为context并不是Activity类型,故没有任务栈,所以便无法运行Activity,解决方法是为待启动的Activity指定FLAG_ACTIVITY_NEW_TASK标志位,为它启动一个新的任务栈,即相当于以singleTask模式(见下文)启动。


2. singleTop:栈顶复用模式。如果Activity的实例已经存在于栈顶,则不会创建新的实例,而是调用它的onNewIntent方法,不会调用onCreate、onStart。如果其实例存在但不是在栈顶,则依然会重新创建新实例。


3. singleTask:栈内复用模式:只要Activity实例已经存在于栈内,则无论启动多少次该Activity都不会创建新的实例,而是将原先该实例上面的其他实例出栈,使该实例调到栈顶,并回调其onNewIntent方法;但如果该Activity的实例不在该栈中,则会创建一个新的任务栈来放置这个新建的实例。


4. singleInstance:单实例模式。singleTask的加强版,除了具有singleTask的所有特性,还要求此种模式下的Activity只能单独位于一个栈中。一旦创建了一个实例后,后面对该Activity的任何请求都不会创建新的实例。


说了这么多,如何指定启动模式呢?

第一种,在AndroidMenifest.xml中为Activity指定,如android:launchMode=“singleTask”;

第二种,通过在Intent中设置标志位,如intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)。

区别在于:第二种优先级大于第一种,当两种同时存在时,以第二种为准;同时,第一种无法直接为Activity设定FLAG_ACTIVITY_CLEAR_TOP标志,而第二种无法指定singleInstance模式。






猜你喜欢

转载自blog.csdn.net/reakingf/article/details/51793434
今日推荐