【Android 高级架构师系统学习文章】Android 基础 -Activity 全方位解析
(7) onDestory():表示 Activity 即将销毁,这是 Activity 生命周期的最后一个回调,可以做一些回收工作和最终的资源回收。
在平常的开发中,我们经常用到的就是 onCreate()和 onDestory(),做一些初始化和回收操作。
生命周期的几种普通情况
①针对一个特定的 Activity,第一次启动,回调如下:onCreate()->onStart()->onResume()
②用户打开新的 Activiy 的时候,上述 Activity 的回调如下:onPause()->onStop()
③再次回到原 Activity 时,回调如下:onRestart()->onStart()->onResume()
④按 back 键回退时,回调如下:onPause()->onStop()->onDestory()
⑤按 Home 键切换到桌面后又回到该 Actitivy,回调如下:onPause()->onStop()->onRestart()->onStart()->onResume()
⑥调用 finish()方法后,回调如下:onDestory()(以在 onCreate()方法中调用为例,不同方法中回调不同,通常都是在 onCreate()方法中调用)
2.特殊情况下的生命周期
上面是普通情况下 Activity 生命周期的一些流程,但是在一些特殊情况下,Activity 的生命周期的经历有些异常,下面就是两种特殊情况。①横竖屏切换在横竖屏切换的过程中,会发生 Activity 被销毁并重建的过程。
在了解这种情况下的生命周期时,首先应该了解这两个回调:onSaveInstanceState 和 onRestoreInstanceState。
在 Activity 由于异常情况下终止时,系统会调用 onSaveInstanceState 来保存当前 Activity 的状态。这个方法的调用是在 onStop 之前,它和 onPause 没有既定的时序关系,该方法只在 Activity 被异常终止的情况下调用。当异常终止的 Activity 被重建以后,系统会调用 onRestoreInstanceState,并且把 Activity 销毁时 onSaveInstanceState 方法所保存的 Bundle 对象参数同时传递给 onRestoreInstanceState 和 onCreate 方法。因此,可以通过 onRestoreInstanceState 方法来恢复 Activity 的状态,该方法的调用时机是在 onStart 之后。其中 onCreate 和 onRestoreInstanceState 方法来恢复 Activity 的状态的区别:?onRestoreInstanceState 回调则表明其中 Bundle 对象非空,不用加非空判断。onCreate 需要非空判断。建议使用 onRestoreInstanceState。
横竖屏切换的生命周期:onPause()->onSaveInstanceState()-> onStop()->onDestroy()->onCreate()->onStart()->onRestoreInstanceState->onResume()
可以通过在 AndroidManifest 文件的 Activity 中指定如下属性:
android:configChanges = "orientation| screenSize"
来避免横竖屏切换时,Activity 的销毁和重建,而是回调了下面的方法:
@Overridepublic void onConfigurationChanged(Configuration newConfig) {super.onConfigurationChanged(newConfig);}
②资源内存不足导致优先级低的 Activity 被杀死 Activity 优先级的划分和下面的 Activity 的三种运行状态是对应的。
(1) 前台 Activity——正在和用户交互的 Activity,优先级最高。
(2) 可见但非前台 Activity——比如 Activity 中弹出了一个对话框,导致 Activity 可见但是位于后台无法和用户交互。
(3) 后台 Activity——已经被暂停的 Activity,比如执行了 onStop,优先级最低。
当系统内存不足时,会按照上述优先级从低到高去杀死目标 Activity 所在的进程。我们在平常使用手机时,能经常感受到这一现象。这种情况下数组存储和恢复过程和上述情况一致,生命周期情况也一样。
3.Activity 的三种运行状态
①Resumed(活动状态)
又叫 Running 状态,这个 Activity 正在屏幕上显示,并且有用户焦点。这个很好理解,就是用户正在操作的那个界面。
②Paused(暂停状态)
这是一个比较不常见的状态。这个 Activity 在屏幕上是可见的,但是并不是在屏幕最前端的那个 Activity。比如有另一个非全屏或者透明的 Activity 是 Resumed 状态,没有完全遮盖这个 Activity。
③Stopped(停止状态)
当 Activity 完全不可见时,此时 Activity 还在后台运行,仍然在内存中保留 Activity 的状态,并不是完全销毁。这个也很好理解,当跳转的另外一个界面,之前的界面还在后台,按回退按钮还会恢复原来的状态,大部分软件在打开的时候,直接按 Home 键,并不会关闭它,此时的 Activity 就是 Stopped 状态。
二、Activity 的启动模式
1.启动模式的类别
Android 提供了四种 Activity 启动方式:
标准模式(standard)栈顶复用模式(singleTop)栈内复用模式(singleTask)单例模式(singleInstance)
2.启动模式的结构——栈
Activity 的管理是采用任务栈的形式,任务栈采用“后进先出”的栈结构。
3.Activity 的 LaunchMode
(1)标准模式(standard)
每启动一次 Activity,就会创建一个新的 Activity 实例并置于栈顶。谁启动了这个 Activity,那么这个 Activity 就运行在启动它的那个 Activity 所在的栈中。
例如:Activity A 启动了 Activity B,则就会在 A 所在的栈顶压入一个新的 Activity。
![](https://upload-images.jianshu.io/upload_images/22459598-7c47e9ae326d733b.png?imageMogr2/auto-
orient/strip%7CimageView2/2/w/1240)
特殊情况,如果在 Service 或 Application 中启动一个 Activity,其并没有所谓的任务栈,可以使用标记位 Flag 来解决。解决办法:为待启动的 Activity 指定 FLAG_ACTIVITY_NEW_TASK 标记位,创建一个新栈。
应用场景:?绝大多数 Activity。如果以这种方式启动的 Activity 被跨进程调用,在 5.0 之前新启动的 Activity 实例会放入发送 Intent 的 Task 的栈的顶部,尽管它们属于不同的程序,这似乎有点费解看起来也不是那么合理,所以在 5.0 之后,上述情景会创建一个新的 Task,新启动的 Activity 就会放入刚创建的 Task 中,这样就合理的多了。
(2)栈顶复用模式(singleTop)
如果需要新建的 Activity 位于任务栈栈顶,那么此 Activity 的实例就不会重建,而是重用栈顶的实例。并回调如下方法:
@Overrideprotected void onNewIntent(Intent intent) {super.onNewIntent(intent);}
由于不会重建一个 Activity 实例,则不会回调其他生命周期方法。如果栈顶不是新建的 Activity,就会创建该 Activity 新的实例,并放入栈顶。
应用场景:?在通知栏点击收到的通知,然后需要启动一个 Activity,这个 Activity 就可以用 singleTop,否则每次点击都会新建一个 Activity。当然实际的开发过程中,测试妹纸没准给你提过这样的 bug:某个场景下连续快速点击,启动了两个 Activity。如果这个时候待启动的 Activity 使用 singleTop 模式也是可以避免这个 Bug 的。同 standard 模式,如果是外部程序启动 singleTop 的 Activity,在 Android 5.0 之前新创建的 Activity 会位于调用者的 Task 中,5.0 及以后会放入新的 Task 中。
(3)栈内复用模式(singleTask)
该模式是一种单例模式,即一个栈内只有一个该 Activity 实例。该模式,可以通过在 AndroidManifest 文件的 Activity 中指定该 Activity 需要加载到那个栈中,即 singleTask 的 Activity 可以指定想要加载的目标栈。singleTask 和 taskAffinity 配合使用,指定开启的 Activity 加入到哪个栈中。
评论