Activity可以说是我们平常使用最多的组件了,虽然使用起来似乎很简单,但是如果深入了解的话,其实还是有很多需要我们注意的地方的。
Activity生命周期
正常情况下的生命周期
Fragment的生命周期
Activity和Fragment的生命周期之间的关联
看完上面的图,我们大致对生命周期有了一个认识,可以看到生命周期基本都是两两对应的。
- onCreate()与onDestory()分别对应与创建与销毁。
- onStart()与onStop()分别对应Activity的是否可见。
- onReume()与onPause()分别对应着用户是否能够进行交互。
Activity A启动一个新的Activity B怎么执行生命周期,为什么会这样呢?
A onPuase()->B onCreate()->B onStart()->B onReusme()->A onStop();
Android这样设计的主要目的是为了提高Activity的启动速度。
调用finish()方法会生命周期会走什么流程?
Fragment的add()、remove()、replace()方法生命周期会如何执行?
- add()将会正常的走创建流程。
onAttach()->onCreate()->onCreateView()->onActivityCreated()->onStart()->onResume()->Fragment is activie
- remove()将会正常的走销毁流程。
onPause()->onStop()->onDestoryView()->onDestroy()->onDetach()
- replace()将会先走销毁流程再走创建流程。
异常情况下的生命周期
- Activity因为系统内存过低导致被回收或者App突然Crash生命周期如何执行
onPause()->onSaveInstanceState(Bundle )->...->onCreate()->onRestoreInstanceState()
- 系统资源发生变化导致的Activity重新创建
例如屏幕出现了旋转,或者输入法的显示与隐藏都会导致App重新创建,虽然引起重建的原因不同,但是生命周期的执行与上面的情况是一致的。
不过我们也可以手动设置当某些资源发生变化不去重新创建Activity()
设置的方法就是在manifeset文件中添加属性configChanges
android:configChanges="orientation"
上面的属性就代表着手机屏幕方向发生改变时不去重新创建Activcity。
完整的系统资源属性有以下这些
mmc:这里的意思是SIM卡的标识IMSI中的mmc发生了改变,这个mmc的用途是区分不同的国家的3位数号码,比如中国的是460,玩过水货的估计有了解这个东西的。
mnc:IMSI中的运营商代码改变,就是用来区分当前SIM卡的网络运营商的,中国移动是00,联通是01,电信是03。
locale:本地位置改变触犯,恩,这个貌似跟语言切换有关,没用过,不是跟了解。
keyboard、keyboardHidden:这两个一起说一下,就是跟键盘有关的操作,前一个是键盘类型变化,如插了个键盘在设备上,后一个指的是键盘的可访问性发生变化。
teachScreen:触摸屏变化。
navigation:系统导航方式变化。
screenLayout:屏幕布局发生了改变。
layloutDirection:布局的方向发生变化,注意,是布局的方向,不是屏幕的,比较难理解的一个概念,是API17之后出现的
rientation:屏幕方向改变,具体就是屏幕的横竖屏切换。
uiMode:用户界面改变,这个是api18后出现的,比如切换夜间模式等场景会出现这个。
fontScale:系统字体大小改变。
screenSize:设备的屏幕的尺寸信息发生了改变,旋转屏幕时也会触发这个,但是这个值是API13之后才有的,因此13之前的设备没有这个。
smallestScreenSize:设备的物理屏幕发生改变,同样是API13之后的东西,指的是设备的物理屏幕发生变化,比如外接显示器之类的。。。大体上是这个意思。
Activity的启动模式
Activity的启动模式共有四种:
Standard:标准的启动模式,每次启动Activity的创建生命周期都会调用,并且将此Activity压入栈中。
SingleTop:栈顶复用模式,如果Activity已经被创建并且位于栈顶,那么将不会再创建此实例,也就是说onCreate()
不会被调用,而是会执行另外一个方法onNewIntent(Intent intent)
方法。
SingleTask:栈内复用模式,这种启动模式在启动前会判断是否存在改Task栈,如果不存在则先创建Activity栈,然后入栈。
如果已经存在则判断栈内是否已经存在实例,不存在则创建实例进行入栈,存在则先执行clear_top操作,也就是说把实例上方的其它实例出栈。
SingleInstance:强化的SingleTask
模式,与SingleTask不同的是以这种模式启动的Activity会单独的处于一个回退栈中,
使用场景:
SingleInstance
例:电话的来电界面,按返回键后会自动后退到Launcher界面,不管任何情况下这个系统只会存在一个通话界面。
SingleTask:
例:App的主界面,某个App一般情况下只会打开一次主界面,App中经常需要提供返回首页的功能,于是我们就能够利用这种启动模式,在返回主界面的同时将其它已经打开的Activity进行出栈操作。
启动时的flag:
-
FLAG_ACTIVITY_NEW_TASK
作用是为Activity指定 “SingleTask”启动模式。跟在AndroidMainfest.xml指定效果同样。 -
FLAG_ACTIVITY_SINGLE_TOP
作用是为Activity指定 “SingleTop”启动模式,跟在AndroidMainfest.xml指定效果同样。 -
FLAG_ACTIVITY_CLEAN_TOP
具有此标记位的Activity,启动时会将与该Activity在同一任务栈的其他Activity出栈。一般与SingleTask启动模式一起出现。它会完毕SingleTask的作用。但事实上SingleTask启动模式默认具有此标记位的作用
4.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
具有此标记位的Activity不会出如今历史Activity的列表中,使用场景:当某些情况下我们不希望用户通过历史列表回到Activity时,此标记位便体现了它的效果。它等同于在xml中指定Activity的属性:
android:excludeFromRecents="trure"
IntentFilter
启动组件时可以使用显式启动与隐式启动,隐式启动时根据注册时的Action、Category、date,通过IntentFilter的方式来区别隐式启动时具体需要启动哪个组件。
参考文档: