Activity是Android组件中最基本也是最为常见用的四大组件(Activity,Service,Content Provider,BroadcastReceiver)之一;
本篇主要从以下几点来详解Activity
*Activity的生命周期
*Activity的启动模式
一、Activity的生命周期
可以看到Activity有7个最基本的生命周期方法
1.onCreate:Activity即将被创建;
2.onStart:表示Activity正在被启动,已经可见了,但是还没有显示到前台;
3.onRestart:Activity正在重新启动,当Activity从不可见到可见时会调用此方法;
4.onResume:Activity可见,并且已经显示到前台可以和用户交互了;(onStart的时候Activity还在后台,在onResume后Activity才显示到前台)
5.onPause:Activity正在停止(可见但不在前台);
6.onStop:Activity即将停止(不可见亦不在前台);
7.onDestroy:Activity即将销毁;
接下来我们从几个实例中来具体了解一下Activity的生命周期;
首先:我们正常启动一个Activity
然后我们回到桌面:
我们再次打开这个Activity
在这个Activity上再启动一个Dialog形式的Activity,第一个Activity任然可见,但是已经转入后台
然后我们退出Dialog返回第一个Activity
从第一个Activity跳转到另一个Activity(非Dialog形式)
再推出第二个Activity返回第一个
最后我们退出第一个Activity
这里有几点需要注意:
1、onCreate和onDestroy、onStart和onStop、onResume和onPause是配对的,其中
onPause和onResume与onStart和onStop的区别在于前者是以是否在前台显示来判断的后者是以是否可以见来区分的;
2、从一个Activity启动另一个Activity,第一个Activity会首先onPause,紧接着第二个Activity开始onCreate、onStart、onResume后,第一个Activity执行onStop;一定要注意跳转时候Activity的生命周期方法执行顺序;
特别说明:如果在一个Activity上启动了一个Dialog(非Activity形式),这时候Activity虽然可见,但是不在前台,Activity是不会执行onPause方法的;
下面我们来研究一下异常情况下Activity的生命周期,所谓异常情况就是资源相关的系统配置发生改变导致Activity被杀死并重建或者资源内存不足导致优先级低的Activity被系统回收等等;最常见的就是横竖屏切换,Activity状态会发生那些改变呢;
首先我们正常启动一个Activity:
正常的走了生命周期的方法;
然后我们从竖屏切换到横屏:
这里我们可以看到,Activity销毁了并重新创建,Activity在销毁之前调用了onSaveInstanceState,并且在Activity重新创建成功后调用了onRestoreInstanceState方法;
onSaveInstanceState:Activity异常销毁保存Activity数据和状态;
onRestoreInstanceState:Activity异常销毁重新创建后恢复数据;
注意:以上方法只会在Activity异常销毁的时候调用,正常情况下是不会调用的;
另外还有一种特殊情况,我们在某些状态改变导致Activity销毁重建如果不希望Activity重新创建,例如横竖屏切换不希望Activity重新创建需要在清单文件中Activity中配置 android:configChanges="orientation" (需要minSdkVersion和targetSdkVersion的值都小于13否则需要配置android:configChanges="orientation|screenSize")
我们来看一下效果,添加以上配置后,我们将Activity从竖屏切换到横屏
可以看到Activity并没有重建,而是调用了onConfigurationChanged方法;
通过上面的分析,我们已经了解了Activity的生命周期,以及Activity在特殊情况下的生命周期;掌握了Activity的生命周期,就可以在不同的方法中做相应的处理,对以后的开发很有帮助;
二、Activity的启动模式
①standard:标准模式,系统默认模式,最常用;
②singleTop:栈顶复用模式,如果Activity位于任务栈内栈顶位置Activity不会重新创建;
③singleTask:栈内复用模式,只要Activity在栈内存在,多次启动Activity就不会重新创建;
④singleInstance:单实例模式;这种模式下,Activity只能单纯的存在一个任务栈中;
注意:任务栈是一种“后进先出”栈结构,每一个Activity都必须依赖一个任务栈,这也是为什么我们用ApplicationContext去启动Activity的时候会报错的原因;standard模式下的Activity默认会进入启动它的Activity的任务栈中;非Activity类型的Context(ApplicationContext)并没有所谓的任务栈,所以就出问题了,解决这个问题就需要为待启动的Activity指定 FLAG_ACTIVITY_NEW_TASK 标记位,这样就会在启动的时候为其创建一个新的标记位;
启动模式解读:
1、standard标准模式:每启动一次Activity,都会为这个Activity创建实例;
2、singleTop模式:假如在一个任务栈中有ABC三个Activity(都是singleTop启动模式),如果再次启动C,由于C在栈顶,那么C就不会被重新创建同时它的onNewIntent方法会被回调;如果启动A,由于A不在栈顶,A就会被重新创建;
3、singleTask模式:假如一个任务栈中有ABC三个Activity,(A为singleTask模式),A并不在栈顶,我们重新启动A,A也并不会创建新的,而是直接移到栈顶并调用A的onNewIntent方法;此时栈内的Activity为 A ,因为singleTask模式自带clearTop的效果,会导致所有在A上面的Activity自动出栈;
4、singleInstance模式:这个是加强版的singleTask模式,它具有singleTask的所有特性;并且还加强了一点,这种模式下的Activity只能单独的位于一个任务栈中,加入A为这种启动模式,启动A后,A单独位于一个任务栈中,这个任务栈中只能有一个Activity A;
注意:由于Activity启动必须依赖任务栈,任务栈是可以指定的,可以在清单文件中配置android:taskAffinity=“”熟悉,任务栈的名字为String,如果不指定,进入默认的任务栈,即以包名为名的任务栈;
如何给Activity指定启动模式
第一种方式:直接在AndroidMenifest中指定 android:launchMode
第二种方式:通过Intent中设置标志位来为Activity指定
Intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
两种方式的区别:第二种优先级大于第一种,如果两种方式都用了,以第二种方式执行;第二种方式无法为Activity指定为singleInstance模式;
Activity中的标志位:
1、FLAG_ACTIVITY_NEW_TASE:为Activity指定singleTask启动模式
2、FLAG_ACTIVITY_SINGLE_TOP:singleTop模式
3、FLAG_ACTIVITY_CLEAR_TOP:当这个Activity启动时所用位于它之上的Activity全部出栈;
4、FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS:具有这个标记的Activity,不会出现在历史Activity列表中;某种情况下,我们不希望用户通过历史列表回到我们的Activity时这个标记比较有用;等同于在XML中指定Activity的属性
android:excludeFromRecents="true"
小结:本次的Activity详解一共就这些内容主要点为
1、Activity的生命周期,Activity从启动到销毁,从前台到后台,不同情况下Activity的哪些生命周期方法会被调用;以及Activity在异常销毁后重新创建要调用的方法;
2、Activity的启动模式;不同的场景应用不同的启动模式,各个启动模式间的区别;了解这些对以后的开发很有帮助;