Android Activity生命周期和启动模式

假如编程易懂得,那么程序员就不会热情地写出注释,也不会有得到编程的快乐。

这周六周日是在是太忙了,导致博客没有及时更新,在这里深表惭愧,所以这才加班加点完成一篇博客来弥补我的过失,好了不说那么多了,进入正题,今天主要讲的是 Activity 的声明周期和启动模式,其实这两个地方的基础知识本篇不会介绍很多,本篇主要介绍的是我们在使用中遇到的问题,和我们在使用中正确的使用规则。


一、概述


       1、当我提起 Activity 的生命周期的时候,你会很容的回答出,onCreate 、onStart、onResume、onPause、onStop、onDestory 等一些回调方法,那每个回调中,我们应该做什么事情,不应该做什么事情或许你就很迷惑了,那今天我们在这篇文章中将会问你排忧解惑。

       2、Activity 的启动模式在我看来也是一个很有意思的东西,我们可以通过设置 launchMode 这个属性指定我们的 Activity 的启动模式,我们通常的 Activity 启动模式都是 standard ,有时候会用到 singleTop 和 singleTask,其实我认为最有意思的就是这个 singleInstance,那今天我们就来说说我们在使用这四种启动模式遇到的问题。


二、Activity 生命周期



       2.1 正常情况下的声明周期

             onCreate:

             这个方法其实不用我们多说了,一般只会执行一次,就是进行一些初始化等操作,这个方法中有一个

      Bundle 值,这个值在我们正常启动的时候会是空的,所以我们判断是否为正常启动就判断一些这个 Bundle是否         为空就可以了。


             onStart:

             当回调这个方法的时候,说明我们的 Activity 已经可见了,但是还没有出现在前台,你可以这样理解,这个方        法执行的时候,我们的 Activity 已经可见了,只是我们还看不到。


              onRestart:

              这个方法是我们重新启动的时候会回调的,当我们的 Activity 从可见到不可见,再由不可见变为可见,这个          方法就会调用,这个方法和用户的操作息息相关,比如用户点了 home 再次回到 APP,或者用户从 A 界面到 B          界面,然后点击了返回键都会回调这个方法。


              onResume:

              这个方法和 onStart 的区别就是当这个方法回调的时候,Activity 已经出现在前台了,onStart 回调的时候               Activity 还在后台,所以当回调这个方法的时候,Activity 已经可见了。


              onPause:

             这个方法表示 Activity 正在停止,正常情况下,这个方法执行之后就会执行 onStop 方法,不过在极端情况             下,当用户迅速点击返回键的时候,会直接执行 onResume 方法。因为只有这个方法执行完成,新的 Activity 的         onResume 方法才会执行,所以不要在这个方法中执行一些耗时的操作,因为如果执行耗时操作的话,跳转会慢         很多。


              onStop:

              这个方法执行的时候表示 Activity 即将停止,可以做一些相对耗时的操作,同样不能太耗时。注意:如果                Activity 使用了透明主题,那么不会回调这个 onStop 方法。


              onDestory:

              此方法执行之后表示 Activity 正式被销毁,那在这个方法中我们一定要执行资源回收和释放,不然很容易引           起内存泄漏。


        最后提出一个问题 onStart 和 onResume ,onPause 和 onStop 有什么不同?

        答:对于我们使用,那么最主要的区别就是 onStart 和 onStop 主要是区分 Activity 是否可见来回调的,那                          onPause 和 onResume 主要是区分 Activity 是否位于前台来区分的。


       2.2 异常情况下的声明周期

             首先说一下, 我们的 Activity 的三种运行状态:

             ①、前台 Activity ,也就是正在和用户进行交互的 Activity。

②、可见但是非前台的 Activity,也就是说这个 Activity 弹出了一个 dialog 导致 Activity 可见但是位于后台

无法交互

③、后台 Activity,已经被暂停的 Activity,比如执行了 onStop。


这三种 Activity 最有可能被回收内存的就是第三种,那么被回收的 Activity 重新打开的生命周期和我们正常
打开的生命周期肯定是不一样的,那么我们下面就说一下异常情况下的 Activity 的生命周期中增加了哪些。
说到内存重启,我们不得不说一下我们在注册 Activity 的时候指定的 configChange 属性,指定这个属性的时候
我们可以指定哪些地方不用重启 Activity ,例如可以指定 :
locale(设备本地位置改变,一般指切换了语言)
orientation (屏幕的旋转)
keyboardHidden(键盘的可访问发生了改变)
如果指定多个可以用 | 进行隔开。


好了下面说一下异常情况的生命周期:
onSaveInstanceState:这个方法一般执行在 onStop 之前,不一定执行在 onPause 之前或者之后,一定
要记住,这个方法只有在异常的时候才会回调的。
onRestoreInstanceState:这个方法一般是我们恢复数据的时候要去实现的,在 onStart 方法之后执行,
这个方法中有一个 Bundle 恢复数据的时候也是根据这个 Bundle 去恢复的。其实在恢复数据的时候大部分
的数据系统都是帮我们恢复好的,比如 Listview 的位置,还有 View 填写的信息等,如果想知道到底恢复了
哪些数据,可以看一下每个 View 的源码,每个 View 中都有 Save 和 Restore 方法的。
最后说一下异常时候保存数据的流程,首先是 Activity 的 onSaveIntanceState 去保存数据,然 Activity委托
window 去保存数据,最后,window 再去委托 DecorView 去保存数据,最后 DecorView 在去通知每个 View
保存数据,这样就完成了保存数据的整个流程。

三、启动模式

       


       启动模式的指定可以改写我们 Activity 栈的顺序,从而修改我们返回的 Activity,我认为最大的作用就是我们的返        回退出。启动模式可以通过 lunchMode 指定。 好了不说这些,下面说正题,Activity 的四种启动模式。

       

       ①、standard

        定义我就不再这里说明了,这里说一个我们在使用中遇到的问题,在我们用 Application 的 context 去进行跳转           的时候,我们会跳转失败,因为我们新启动的 Activity 需要一个 task,而 context 没有 task,这样就会出现问             题,解决办法就是我们跳转的时候给 Activity 指定一个 task。

        当我们启动一个 Activity 的时候指定了一个 task ,那么系统会先创建 task 再去创建 Activity 。


       ②、singleTop

        这个启动模式知识点也就一个,那就是当我们启动的 Activity 在栈顶的时候,这个 Activity 会调用 onNewIntent           方法。


       ③、singleTask

        singleTask 和 singleTop 最大的区别就是会执行 clearTop 操作。clearTop 操作会将目标 Activity 上面的全

部 Activity 出栈。


       ④、singleIntance

        它是 singleTask 的加强版,当我们启动一个新的 Activity 回去重新创建一个 Task,这样我们的 Activity 就运行在

        一个独立的 Task 中。

   

        下面说几种特殊情况:

         

1、当 B 启动模式为 singleInstance 的时候, A -> B B为一个 task, B->C 那么 C 的 task 和 A的 task 是相
同的。 也就是说 C 被压在 A 的上面了。但是如果从外部程序启动 B ,B 在启动 C 那么 other -> B -> C 这三个的
taskid 是都不相同的


2、AB在前台任务栈,CD在后台任务栈,CD启动得 lunchMode 为 singleTask,这时我们访问
D,这个时候会把 CD 放到前台任务栈,所以现在前台任务栈为 ABCD 。

        上文中我们多次提到了 Task,那么这个 Task 到底是什么呢,下面看看我的理解:


Task: 这个 task 是标识 Activity 存储在哪里的,每个 Activity 都会有一个 task 存储,每个 Activity 的 task 名
字都是应用的包名,所以当我们想指定 task 的时候不能指定和包名一样。这个 task 分为前台 task 和后台
task,后台 task 都是存储暂停的 Activity。
allowTaskPeparenting :当我们给某个 Activity 的这个属性设置为 true 的时候,当我们从应用 A 启动应用 B
的 Activity 的时候,并且这个 Activity 设置了 allowTaskPeparenting = true,那么 B 的 Activity 的 Task 会从
A 的 task 转到了 B 的task。也就是说我们只要启动了 B 的任何一个 Activity ,那么 B 的 Task 就会创建出来。
在 AndroidManiFest 中可以通过指定 taskAffinity 属性来指定 Activity 的 task,不过包名中间必须有分隔符。




四、使用中注意的问题


       1、当我们每次新启动一个 Activity 的时候,我们的旧 Activity 的 onPause 方法总会最先调用,所以在我们跳                    转的时候不要在 onPause 方法中执行耗时的代码,这样会导致跳转缓慢。


       2、有两种方法可以指定 lunchMode 一种是配置,一种是在 Intent 中设置,后者的优先级高于前者。




总结:

       这些都是在项目中总结出来的一些经验,如果有什么出入欢迎指出,我们共同进步。谢谢。


       雅歌不会编代码

       2017/07/10



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值