Android Activity为什么要细化出onCreate、onStart、onResume、onPause、onStop、onDesdroy这么多方法让应用去重载?
原文:http://www.xuebuyuan.com/1608083.html
最近在研究Activity的启动流程,老罗的blog在看,也找了其它资料学习,也跟过Android4.3的源码,
在跟代码的过程中,突然想到下面的这个问题:
Android Activity为什么要细化出onCreate、onStart、onResume、onPause、onStop、onDesdroy这么多方法让应用去重载?
网上太多根据Android开发规范翻译转载的内容,都不是我想要的答案,那就自己分析下。
如下是一段典型的Activity间切换的日志,从AActivity切换到BActivity:
10-17 20:54:42.247: I/com.example.servicetest.AActivity(5817): onCreate() 1166919192 taskID=66
10-17 20:54:42.263: I/com.example.servicetest.AActivity(5817): onStart() 1166919192 taskID=66
10-17 20:54:42.263: I/com.example.servicetest.AActivity(5817): onResume() 1166919192 taskID=66
10-17 20:54:46.997: I/com.example.servicetest.AActivity(5817): onPause() 1166919192 taskID=66
10-17 20:54:47.021: I/com.example.servicetest.BActivity(5817): onCreate() 1166971824 taskID=66
10-17 20:54:47.028: I/com.example.servicetest.BActivity(5817): onStart() 1166971824 taskID=66
10-17 20:54:47.028: I/com.example.servicetest.BActivity(5817): onResume() 1166971824 taskID=66
10-17 20:54:47.099: I/com.example.servicetest.AActivity(5817): onStop() 1166919192 taskID=66
当触发从AActivity切换到BActivity时的日志如下:
10-17 20:54:46.997: I/com.example.servicetest.AActivity(5817): onPause() 1166919192 taskID=66
10-17 20:54:47.021: I/com.example.servicetest.BActivity(5817): onCreate() 1166971824 taskID=66
10-17 20:54:47.028: I/com.example.servicetest.BActivity(5817): onStart() 1166971824 taskID=66
10-17 20:54:47.028: I/com.example.servicetest.BActivity(5817): onResume() 1166971824 taskID=66
10-17 20:54:47.099: I/com.example.servicetest.AActivity(5817): onStop() 1166919192 taskID=66
先AActivity的onPause()被调用,然后是BActivity的初始化流程(onCreate() --> onStart() --> onResume()),再然后是AActivity的onStop()被调用。
有点意思,为什么不是先AActivity的onPause()、onStop()被调用,然后再BActivity的初始化流程(onCreate() --> onStart() --> onResume())?
或者又为什么不是先BActivity的初始化流程(onCreate() --> onStart() --> onResume()),再AActivity的onPause()、onStop()被调用?
如下是Activity的几个关键方法的注释:
void android.app.Activity.onCreate(Bundle savedInstanceState)
Called when the activity is starting. This is where most initialization should go: calling setContentView(int) to inflate the activity's UI, using findViewById to programmatically interact with widgets in the UI, calling managedQuery(android.net.Uri, String[],
String, String[], String) to retrieve cursors for data being displayed, etc.
You can call finish from within this function, in which case onDestroy() will be immediately called without any of the rest of the activity lifecycle (onStart, onResume, onPause, etc) executing.void android.app.Activity.onStart()
Called after onCreate — or after onRestart when the activity had been stopped, but is now again being displayed to the user. It will be followed by onResume.
void android.app.Activity.onResume()
Called after onRestoreInstanceState, onRestart, or onPause, for your activity to start interacting with the user. This is a good place to begin animations, open exclusive-access devices (such as the camera), etc.
Keep in mind that onResume is not the best indicator that your activity is visible to the user; a system window such as the keyguard may be in front. Use onWindowFocusChanged to know for certain that your activity is visible to the user (for example, to
resume a game).void android.app.Activity.onPause()
Called as part of the activity lifecycle when an activity is going into the background, but has not (yet) been killed. The counterpart to onResume.
When activity B is launched in front of activity A, this callback will be invoked on A. B will not be created until A's onPause returns, so be sure to not do anything lengthy here.
This callback is mostly used for saving any persistent state the activity is editing, to present a "edit in place" model to the user and making sure nothing is lost if there are not enough resources to start the new activity without first killing this one.
This is also a good place to do things like stop animations and other things that consume a noticeable amount of CPU in order to make the switch to the next activity as fast as possible, or to close resources that are exclusive access such as the camera.In situations where the system needs more memory it may kill paused processes to reclaim resources. Because of this, you should be sure that all of your state is saved by the time you return from this function. In general onSaveInstanceState is used to save
per-instance state in the activity and this method is used to store global persistent data (in content providers, files, etc.)After receiving this call you will usually receive a following call to onStop (after the next activity has been resumed and displayed), however in some cases there will be a direct call back to onResume without going through the stopped state.
void android.app.Activity.onStop()
Called when you are no longer visible to the user. You will next receive either onRestart, onDestroy, or nothing, depending on later user activity.
Note that this method may never be called, in low memory situations where the system does not have enough memory to keep your activity's process running after its onPause method is called.
如果所有的初始化都在onCreate()中实现,会有什么问题?
首先,Activity的onCreate()被调用时,Activity还不可见,如果要做一些动画,既然视图还不存在,在onCreate中来启动动画,明显有问题;
其次,AActivity 切换到 BActivity,再切换到 AActivity(我们假定是AActivity的同一个实例),由于实例已经存在,所以onCreate不会再被调用,那AActivity从后台切换至前台时,有可能需要一些初始化,那就没法再被调用到了,也有问题;
如果所有的初始化都在onStart()中实现,会有什么问题?
首先,onCreate()注释中,是明确建议 setContentView()、findViewById() 要在 onCreate() 中被调用,但我实测了一下,在onStart()中调用 setContentView()、findViewById() 功能也是正常的;
其次,onStart() 被调用时,Activity可能是可见了,但还不是可交互的,onResume()的注释中都明确地说了这不是Activity对用户是可见的最好的指示器,onStart() 在这之前被调用,那有一些特殊的初始化相关的逻辑在这里被调用也会有问题。
如果把所有的去初始化都在onStop()中实现,会有什么问题?
1、 在 onResume() 的注释中,建议是在onResume()中打开独占设备(比如相机),与onResume()对应的是onPause(),所以所有的去初始化操作放在onStop()中执行,可能会引出新的问题;
2、onStop() 的注释中明确地写了,在内存不足而导致系统无法保留此进程的情况下,onStop() 可能都不会被执行。
我的老Android手机的相机应用如果未正常关闭,相机在不重启系统的情况下就无法再正常启动,估计就和这个机制有关;相机进程是被强制杀掉的,而导致去初始化操作未被正常执行。
Activity间跳转时,为什么是先AActivity的onPause()被调用,然后是BActivity的初始化流程(onCreate() --> onStart() --> onResume()),再然后是AActivity的onStop()被调用?
1、在 onResume() 的注释中,建议是在onResume()中打开独占设备(比如相机),与onResume()对应的是onPause(),关闭相机的操作也应该在此方法中被调用;否则,考虑一下如下场景:
如果AActivity打开了相机,我们点击某按钮要跳转到BActivity中,BActivity也想打开相机;假设AActivity的onPause() 在 BActivity启动后再被调用,
那BActivity根本就无法再正常启动相机。
2、onPause() 的注释中,也明确地说了,在这个方法中执行停止动画等比较耗CPU的操作,如果不先执行这些操作,就先启动新应用,然后再来执行此操作,确实是不合逻辑;
从AActivity切换到BActivity的日志如下:
10-17 20:54:46.997: I/com.example.servicetest.AActivity(5817): onPause() 1166919192 taskID=66
10-17 20:54:47.021: I/com.example.servicetest.BActivity(5817): onCreate() 1166971824 taskID=66
10-17 20:54:47.028: I/com.example.servicetest.BActivity(5817): onStart() 1166971824 taskID=66
10-17 20:54:47.028: I/com.example.servicetest.BActivity(5817): onResume() 1166971824 taskID=66
10-17 20:54:47.099: I/com.example.servicetest.AActivity(5817): onStop() 1166919192 taskID=66
从逻辑的完整性和用户体验的角度来分析,这样实现确实是比较合理的,当用户触发某事件切换到新的Activity,用户肯定是想尽快进入新的视图进行操作,
上面已经说了,在onResume()一般会打开独占设备,开启动画等,
当需要从AActivity切换到BActivity时,先执行AActivity中的与onResume()相对应的onPause()操作,比如关闭独占设备,关闭动画,或其它耗费cpu的操作;
以防止BActivity也需要使用这些资源,关闭耗CPU的操作,也有利于BActivity运行的流畅。
底层执行AActivity的onPause()时,有一定的时间限制的,当ActivityManagerService通知应用进程暂停指定的Activity时,如果对应的onPause()在500ms内还没有执行完,ActivityManagerService就会强制关闭这个Activity。如下就是对应的onPause()执行超时常量定义:
// How long we wait until giving up on the last activity to pause. This
// is short because it directly impacts the responsiveness of starting the
// next activity.
static final int PAUSE_TIMEOUT = 500; // 定义在ActivityStack.java中
AActivity中比较消耗资源的部分关闭后,再切换到BActivity中执行BActivity的初始化,显示BActivity中的View。
当BActivity已经执行显示出来了,用户可以交互,后台再去执行AActivity的onStop()操作,即使这里面有些比较耗时的操作,也没有关系,这是在后台执行所以也不影响用户的体验。
Android Activity为什么要细化出onCreate、onStart、onResume、onPause、onStop、onDesdroy这么多方法让应用去重载?的更多相关文章
- 【Android】详解Android Activity
目录结构: contents structure [+] 创建Activity 如何创建Activity 如何创建快捷图标 如何设置应用程序的名称.图标与Activity的名称.图标不相同 Activ ...
- Android Activity生命周期的几个问题
每一个Android开发者都应该知道,android系统有四个重要的基本组件,即Activity(活动).Service(服务).Broadcast Receive(广播接收器)和Content ...
- Android Activity生命周期及启动模式
曾经搞过许多东西,再熟练的东西一段时间没有碰都会生疏或忘记.后来体会到写成文档记录下来的重要性,但有些word或ppt记录下来的东西随着时间流逝会丢失,或者不愿去看.或许保存成博客的形式,会是更好的选 ...
- Android——Activity中的六个主要函数
Android Activity中的六个主要函数 Android中一个Activity一般都需要实现六个函数: onCreate(), onStart(), onResume(),onPause(), ...
- android Activity生命周期的例子
package com.example.yanlei.yl2; import android.app.AlertDialog; import android.content.DialogInterfa ...
- [转]: 两分钟彻底让你明白Android Activity生命周期(图文)!
转自:http://blog.csdn.net/android_tutor/article/details/5772285 大家好,今天给大家详解一下Android中Activity的生命周期,我在前 ...
- Android Activity 详述
activity类处于android.app包中,继承关系: extends ContextThemeWrapper implements LayoutInflater.Factory2 Window ...
- android activity声明周期学习笔记
android生命周期图: Activity继承了ApplicationContext: 1:初次加载activity时顺序执行:onCreate()-->onStart()-->onRe ...
- Android Activity生命周期以及Fragment生命周期的区别与分析
Android Fragment生命周期图: Activity生命周期图: 对照图: Fragment生命周期分析: 1. 当一个fragment被创建的时候,它会经历以下状态. onAttach() ...
随机推荐
- 关于 vee-validate直接引用的方法
转载于:https://blog.csdn.net/hy111/article/details/79046500?%3E 由于当前项目使用的是基于jQuery的前端结构,尝试在新增需求中使用VUE2, ...
- Linux自学系列 -- 常用指令的使用
1.查看目录下内容>ls //列出目录下的文件信息>ls -l //以“详细信息"查看目录文件>ls -a //查看目录“全部”(包括隐藏文件)文件> ...
- json字符串数组判断其中
嘴挺笨的描述不清,直接看图,console.log(data1)是下图 获取的table中的数据组成的json对象(这里我不明白json对象啊json字符串啊json数组啊.我只会- 需要啥就转换成啥 ...
- 【bzoj4146】[AMPPZ2014]Divisors 数论
原文地址:http://www.cnblogs.com/GXZlegend/p/6801411.html 题目描述 给定一个序列a[1],a[2],...,a[n].求满足i!=j且a[i]|a[j] ...
- 【bzoj4822/bzoj1935】[Cqoi2017]老C的任务/[Shoi2007]Tree 园丁的烦恼 树状数组
原文地址:http://www.cnblogs.com/GXZlegend/p/6825530.html bzoj4822 题目描述 老 C 是个程序员. 最近老 C 从老板那里接到了一个任务 ...
- POJ 3264 Balanced Lineup | st表
题意: 求区间max-min st表模板 #include<cstdio> #include<algorithm> #include<cstring> #inclu ...
- CI的多级目录的功能
https://segmentfault.com/q/1010000008317555?_ea=1621531
- Multiplication Game(博弈论)
Description Alice and Bob are in their class doing drills on multiplication and division. They quick ...
- 从零开始--Spring项目整合(1)使用maven框架搭建项目
这些年一直在用spring的框架搭建项目,现在开始我们从零开始利用Spring框架来搭建项目,目前我能想到有Spring.SpringMVC.SpringJDBC.Mybatis.WebSockt.R ...
- 母函数(Generation Function) 入门 + 模板
转自:母函数 入门 + 模板 感谢 在数学中,某个序列的母函数(Generating function,又称生成函数)是一种形式幂级数,其每一项的系数可以提供关于这个序列的信息.使用母函数解决问题的 ...