Activity 的生命周期和启动模式

Activity 的生命周期

了解 Activity 的生命周期可以更好的了解每个页面不同时刻的状态,根据不同的状态我们可以进行相应的操作。比如在 Activity 启动时对数据的初始化,在 Activity 关闭时对不需要的数据进行释放。

正常的生命周期

在正常情况下,Activity 会经历如下生命周期;

Activity的生命周期图

  • onCreate()
    表示 Activity 正在创建,这时 Activity 生命周期的第一个方法,可以在这里做一些初始化操作,比如 setContentView 去加载布局资源,以及初始化 Activity 页面显示所需的其他数据。

  • onRestart()
    表示 Activity 正在重新启动,调用时机是:当用户按下 Home 键切换到桌面或者用户打开了一个新的 Activity 接着用户又回到这个 Activity 。

  • onStart()
    表示 Activity 正在被启动,这时候 Activity 已经可见(相对系统是可见)但是还没显示在前台,还无法和用户进行交互。

  • onResume()
    表示 Activity 已经可见了,并且可以和用户交互。

  • onPause()
    表示 Activity 正在定制,正常情况下,紧接着 onStop 就会被调用。此时可以做一些存储数据、停止动画等工作,但是注意不能太耗时,因为这会影响到新 Activity 的显示。

  • onStop()
    表示 Activity 即将停止,可以做一些稍微重量级的回首工作,同样不能太耗时。

  • onDestroy()
    表示 Activity 即将被销毁,这时 Activity 生命周期中的最后一个回调,在这里我么可以做一些回首工作和最终的资源释放。

特殊情况:
当用户打开新的 Activity 或者切换到桌面的时候,如果新的 Activity 采用了透明主题,那么当前 Activity 不会回掉 onStop .

  • 问题1:onStart 和onresume、onPause和 onStop 从描述上看差不多,对我们有什么实质的不同呢?

答:onStart 和 onStop 是从 Activity 的可见这个角度来回调的,onStart 是相对于系统可见但是对于用户还是不可见且不可交互的,onStop 对于用户和系统都是不可见的并且不可和用户交互。而 onResume 和 onPause 是从 Activity是 是否位于前台这个角度来回调的,在 onResume 时 Activity 可见位于前台且可以和用户交互,onPause 时 Activity 位于后台,不可和用户交互。

  • 问题2:假设当前 Activity 为 A ,如果这时用户打开了一个新 Activity B 那么 B 的 onResume 和 A 的 onPause 哪个先执行?

答:查看源码可知,Activity 的启动过程的源码相当复杂,涉及到 Instrumentation、ActivityThread 和 ActivityManagerService( 简称 AMS )从源码中可以看出新的 Activity 启动前,站定的 Activity 需要先 onPause 后,新的 Activity 才能启动。验证方法是写一个 Demo 通过在各个生命周期打印 Log 查看执行顺序。

非正常的生命周期

比如当资源相关的系统配置发生改变以及系统内存不足时, Activity 就可能被杀死。

  • 资源相关的系统配置发生改变导致 Activity 被杀死并重建

当系统配置发生改变后,Activity 会被销毁,其 onPause、onStop、 onDestroy 均会被调用,同时由于 Activity 是在异常情况下终止的,系统会调用 onSaveInstanceState 来保存当前 Activity 的状态。

onSaveInstanceState 的调用时机是在 onStop 之前,但是不一定在 onPause 之后。

当 Activity 被异常终止且重建后,系统会调用 onRestoreInstanceState, 并把 Activity 销毁时 onSaveInstanceState 保存的 Bundle 数据传递给 onRestoreInstanceState 和 onCreate 方法。

因此可以通过 onRestoreInstanceState 和 onCreate 方法来判断 Activity 是否被重建;而且从时序上来说,onRestoreInstanceState 的调用时机在 onStart 之后。

  • 资源内存不足导致低优先级的 Activity 被杀死

Activity 的优先级情况,从高到低可以分为以下三种:

(1) 前台 Activity :正在和用户交互的 Activity ,优先级最高

(2) 可见但非前台 Activity :比如 Activity中弹出了一个对话框,导致 Activity可见但是位于后台无法和用户直接交互

(3) 后台 Activity :已经被暂停的 Activity,比如执行了 onStop , 优先级最低

Activity 的启动模式

有时候为了满足项目的特殊需求,就必须使用 Activity 的启动模式,所以我们必须要搞清楚它的启动模式和标志位

Activity 为什么需要启动模式?

在默认情况下,当我们多次启动同一个 Activity 的时候,系统会创建多个实例并把它们一一放入任务栈中,当我们按下返回键,这些 Activity 会一一回退。这个任务栈时一种“后进先出”的栈结构,也就是最后进来的 Activity 最先出去。但是当我们多次启动同一个 Activity 系统会重复创建多个实例,Android 在设计idea时候为了解决这个问题,它提供了启动模式来修改系统的默认行为。目前又四种启动模式:standard、singleTop、singleTask、singleInstance.

  • standard

这时系统的默认模式,每次启动一个 Activity 都会重新创建一个新的实例,不管这个实例是否已经存在。

  • singleTop

栈顶复用模式。在该模式下,如果新的 Activity 已经位于任务栈的栈顶,那么此 Activity 不会被重新创建,同时它的 onNewIntent 方法会被回掉,通过重写此方法我们可以取出当前请求的信息。

 protected void onNewIntent(Intent intent) {

   super.onNewIntent(intent);

   setIntent(intent);//must store the new intent unless getIntent() will return the old one

 }
  • singleTask

栈内复用模式。这是一种单实例模式,在该模式下,只有 ACtivity 在一个栈中存在,那么多次启动此 Activity 都不会重新创建实例,和 singleTop 一样,体统也会回调其 onNewInstent。

  • singleInstance

单实例模式。这话i是一种加强的 singleTask 模式,它除了具备 singleTask 的所有特性外,还加强了一点,那就是具有此种模式的 Activity 只能单独的位于任务栈中。

如何给 Activity 设置启动模式呢?

有两种方式,(1)是通过 AndroidMenifest 中为 Activity 指定启动模式 (2) 在 Intent 中设置标志位来为 Activity 指定启动模式。两种方式的优先级是(2)优先于(1),当两种方式存在时,以第二种方式为准。当然这两种方式还是有差异的,比如(1)无法啊直接为 Activity 设置 FLAG_ACTIVITY_CLEAR_TOP标志,而 (2) 无法为 Activity 指定 singleInstance 模式。

  • 通过 AndroidMenifest 中为 Activity 指定启动模式
<activity 
    android:name="..activity.MultiportActivity"
    android:launchMode="singleTask"/><!--指定标志位-->
  • 在 Intent 中设置标志位来为 Activity 指定启动模式
Intent intent = new Intent();
intent.setClass(context, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//指定标志位
context.startActivity(intent);
查看任务栈的命令

adb shell dumpsys activity在导出的信息中重点查看Running activitys

Activity 的 Flags

在 Intent 中设置 Activity 的启动模式时可以通过 Flags 设置,这里的 Flags 不仅仅是可以设置启动模式,还可以影响 Activity 的运行状态。比如设置了 FLAG_ACTIVITY_CLEAR_TOP 的Activity 表示在同一个任务栈中所有位于它上面的 Activity 都要出栈,这个标志位一般会和 singleTask 启动模式一起出现,而且 singleTask 模式是默认具有此标志位的效果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_龙衣

赏杯快乐水喝喝

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值