作为Android四大组件中最为基础的组件,Ativity承担着应用和用户交互的基本任务。
Activity是应用与用户进行交互的单一焦点,基本所有Activity都与用户进行交互。所以Activity负责创建一个Window
,可以通过setContentView
方法加载UI。
Activity经常以全屏窗口
向用户展示用户界面,或者可以通过在theme
中设置windowIsFloating
flag使之变为一个悬浮窗口
,还可以启用多窗口
模式,或将窗口嵌入其他窗口
中。
Activity在系统中以activity stack
的形式进行管理。当一个新的activity启动的时候,一般情况下会被放入当前activity stack
的栈顶,成为running activity
。一般情况下前一个activity依旧会存于与栈中,但是只要栈顶activity还存在就不会回到前台。
注意在屏幕上看到的Activity可能属于不同的activity stack
。
Activity的生命周期方法
老生常谈的问题,Activity的常用生命周期方法一共有7个:
1 | public class Activity extends ApplicationContext { |
其中除了onRestart()
,其余6个生命周期方法均两两成为一对:
1 | onCreate() -> onResume() |
给出Activity的生命周期图导航图:
一张看了无数遍的图,但是其中的细节是经常容易忽略的:
onStop()
方法是否执行取决于该activity是否可见。onRestart()
方法实际上是和onCreate()
方法互补的,activity从无到有的情况回调用onCreate()
方法,而重新启动(还没有被销毁)的activity重新回到前台会调用到onRestart()
方法。
Activity的生命周期状态
根据activity的7个主要生命周期方法,将activity的生命周期状态归纳为3种:
- **entire lifrtime :**对应
onCreate()
到onDestory()
中间的任意时刻和状态,此状态区间内不一定对用户可见。 - **visible lifrtime :**对应
onStart()
到onStop()
中间的任意时刻和状态,此状态区间内对用户可见,但不一定可以进行交互。 - **foreground lifrtime :**对应
onResume()
到onPause()
中间的任意时刻和状态,此状态区间内对用户可见,并且可交互。
Activity的非正常退出(系统kill)
前面提到过,activity在正常情况下退出会调用finish()
方法,调用完整的销毁生命周期:onPause() -> onStop() -> onDestory()
,但当activiy不可见的时候,可能随时被系统kill以释放内存,这个时候并不会经历完成整的销毁生命周期,如下表所示:
方法 | 调用时机 | 是否可以被kill |
---|---|---|
onCreate() | activity创建 | No |
onStart() | activity对用户可见 | No |
onResume() | activity可交互 | No |
onPause() | activity不可交互 | Android 3之后不能被kill |
onStop() | activity不可见 | Yes |
onDestory() | activity销毁 | Yes |
其中我们可以看到onPause()
方法在Android3之后不再可被系统kill掉,也就是说,如果需要持久化用户数据以便后续使用或恢复状态,在onPause()
中全部完成最为保险。
而自从Android P开始,用于保存临时数据的回调onSaveInstanseState()
延迟到onStop()
结束之后调用,这也就意味着在更晚的生命周期方法onStop()
之后进行数据保存和完成fragment transaction也是安全的。
Configuration Changes导致的生命周期变化
Configuration指的是由Configuration
类所定义的属性。
当这个设置发生变化的时候,整个应用的UI都需要同步进行更新以适应新的配置。Activity拥有响应``configuration chages的回调。Configuration Changes
包括如下一些情况:
- 屏幕旋转
- 变更语言
- 其他一些情况
当出现configuration changes
的时候会导致当前的activity通过正常的生命周期销毁。若果这个activity处于visible
状态,则onDestory()
执行完之后会立刻重建,onCreate(Bundle)
中传入的savedInstanceState
就由销毁之前的onSaveInstanceState()
回调生成。
应用中可以通过设置android:configChanges
来避免因configuration changes
导致的activity重建,此时会调用回调方法onConfigurationChanged()
来适配。
注意:
若该变化影响到了配置之外的属性,则不会调用onConfigurationChanged()
回调,会直接对activity进行重建。
ActivityResult影响生命周期
一般情况下我们通过startActivity()
方法启动一个activity,但我们需要被启动的activity返回一个结果给前一个activity时,就需要使用到startActivityForResult()
方法。
当被启动的activity还存在时,就可以调用setResult()
方法将结果返回给启动它的activity,而启动它的activity会调用到onActivityResult()
方法接收数据。
需要注意的是onActivityResult()
的调用是在整个activity生命周期之前的,也就是说调用顺序是onActivityResult() -> onRestart() -> onStart() -> onResume()
Activity进程生命周期
对于Android系统来说每个application process
应该尽可能维持更长时间的存活,但实际上有很多时候都不得不杀死老进程来释放内存资源。系统决定销毁哪个process
与它当前是否正在与用户进行交互是密切相关的。
- **Foreground Activity:**如果一个Activity在前台(位于栈顶),则该activity的状态为
active
或running
。这个状态的activity通常是正在与用户发生交互的。这种情况下如果不出现OOM
系统不回去kill这个进程。 - **Visiable Activity:**如果一个activity 失去焦点但仍然对用户可见,则该activity的状态为
visible
。可能会由一个non-full-sized
或者透明
的activity在原activity之上获得焦点导致。这种activity一定是alive
的。这种情况下如果内存不足以保持foreground activity
存活,则会被系统kill。 - **Background Activity:**当一个activity对用户完全不可见的时候,状态为
stopped
或hidden
,当系统内存不足的时候,可以以call finish
或kill process
的形式终结一个activity,使它的状态变为destoryed
。回收之前回调用onSaveInstanceState(Bundle)
方法对用户状态进行保存,当用户回到被杀死的界面时,在onCreate()
方法对其状态进行恢复。 - **Empty Process:**这里要着重强调一下,空进程并不代表进程中没有执行任何任务。空进程的定义是,在进程中没有任何一个存活的
activity
,service
或者broadcastReciever
。所以如果需要执行后台任务的话一定要将任务放到四大组件中。