Activity的生命周期和启动模式--Activity的生命周期的全面分析
1.典型情况下的生命周期分析
- onCreate:表示Activity正在被创建,这是生命周期的第一个方法。在这个方法中,我们可以做一些初始化工作,比如调用setContentView去加载界面布局资源、初始化Activity所需数据等。
- onRestart:表示Activity正在重新启动。一般情况下,当当前Activity从不可见重新变为可见状态时,onRestart就会被调用。这种情形一般时用户行为所导致的,比如用户按Home键切换到桌面或者用户打开了一个新的Activity,这时当前的Activity就会暂停,也就是onPause和onStop被执行了,接着用户又回到了这个Activity,就会出现这种情况。
- onStart:表示Activity正在被启动,即将开始,这时Activity已经可见了,但是还是没有出现在前台,还无法和用户交互。这个时候其实可以理解为Activity已经显示出来了,但是我们还看不到。
- onResume:表示Activity已经可见了,并且出现在前台并开始活动。要注意这个和onStart的对比,onStart和onResume都表示Activity已经可见,但是onStart的时候Activity还在后台,onResume的时候Activity才显示到前台。
- onPause:表示Activity正在停止,正常情况下,紧接着onStop就会被调用。在特殊情况下,如果这个时候迅速地再回到当前Activity,那么onResume会被调用。笔者地理解是,这种情况属于极端情况,用户操作很难重现这一场景。此时可以做一些存储数据、停止动画等工作,但是注意不能太耗时,因为会影响到Activity地显示,onPause必须先执行完,新地Activity的onResume才会执行。
- onStop:表示Activity即将停止,可以做一些稍微重量级的回收工作,同样不能太耗时。
- onDestroy:表示Activity即将被销毁,这是Activity生命周期中的最后一个回调,在这里,我们可以做一些回收工作和最终的资源释放。
- 针对一个特定的Activity,第一次启动,回调如下:onCreate-->onStart-->onResume.
- 当用户打开新的Activity或者切换到桌面的时候,回调如下:onPause-->onStop。这里又一种特殊情况,如果新Activity采用了透明主题,那么当前Activity不会回调onStop.
- 当用户再次回到原Activity时,回调如下:onRestart-->onStart-->onResume。
- 当用户按back键回退时,回调如下:onPause-->onStop-->onDestory。
- 当Activity被系统回收后再次打开,生命周期方法回调过程和(1)一样,注意只是生命周期方法一样,不代表所有过程都一样,这个问题在下一节会详细说明。
- 从整个生命周期来说,onCreate和onDestory时配对的,分别标识着Activity的创建和销毁,并且只能有一次调用。从Activity是否可见来说onStart和onStop是相配对的,随着用户的操作或者设备屏幕的点亮和熄灭,这两个方法可能被调用多次;从Activity是否在前台来说,onResume和onPause是配对的,随着用户操作或者设备屏幕的点亮和熄灭,这两个方法可能被调用多次。
// We need to start pausing the current activity so the top one// can be resumed...boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving);if (mResumedActivity != null) {pausing = true;startPausingLocked(userLeaving, false);if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Pausing " + mResumedActivity);}
从上述代码可以看出,在新Activity启动之前,栈顶的Activity需要先onPause后,新Activity才能启动。最终,在ActivityStackSupervisor中的realStartActivityLocked方法会调用如下代码。
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,System.identityHashCode(r), r.info,new Configuration(mService.mConfiguration), r.compat,app.repProcState, r.icicle, results, newIntents, !andResume,mService.isNextTransitionForward(), profileFile, profileFd,profileAutoStop);
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {// If we are getting ready to gc after going to the background, well// we are back active so skip it.unscheduleGcIdler();if (r.profileFd != null) {mProfiler.setProfiler(r.profileFile, r.profileFd);mProfiler.startProfiling();mProfiler.autoStopProfiler = r.autoStopProfiler;}// Make sure we are running with the most recent config.handleConfigurationChanged(null, null);if (localLOGV) Slog.v(TAG, "Handling launch of " + r);//这里新Activity被创建出来,其onCreate和onStart会被调用Activity a = performLaunchActivity(r, customIntent);if (a != null) {r.createdConfig = new Configuration(mConfiguration);Bundle oldState = r.state;//这里新Activity的onResume会被调用handleResumeActivity(r.token, false, r.isForward,!r.activity.mFinished && !r.startsNotResumed);//省略...}
从上面的分析可以看出,当新启动一个Activity的时候,旧Activity的onPause会先执行,然后才会启动新的Activity。到底是不是这样呢?我们写一个例子验证下,如下是2个Activity的代码,在MainActivity中点击按钮旧可以跳转到SecondActivity,同时为了分析我们的问题,在生命周期方法中打印出了日志,通过日志我们就能看出他们的调用顺序。
public class MainActivity extends AppCompatActivity {private static final String TAG = "MainActivity";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}@Overrideprotected void onPause() {super.onPause();Log.e(TAG, "onPause");}@Overrideprotected void onStop() {super.onStop();Log.e(TAG, "onStop");}public void btnStartSecondActivity(View view) {Intent intent = new Intent(this, SecondActivity.class);startActivity(intent);}
}
public class SecondActivity extends AppCompatActivity {private static final String TAG = "SecondActivity";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_second);Log.e(TAG, "onCreate");}@Overrideprotected void onStart() {super.onStart();Log.e(TAG, "onStart");}@Overrideprotected void onResume() {super.onResume();Log.e(TAG, "onResume");}
}
2.异常情况下的生命周期分析
@Overridepublic Parcelable onSaveInstanceState() {// Force our ancestor class to save its stateParcelable superState = super.onSaveInstanceState();SavedState ss = new SavedState(superState);ss.progress = mProgress;ss.secondaryProgress = mSecondaryProgress;return ss;}
@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);if (savedInstanceState != null) {//被异常重启ActivityString test = savedInstanceState.getString(EXTRA_TEST);Log.e(TAG, "[onCreate] restore extra_test:" + test);}}@Overrideprotected void onSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);Log.e(TAG, "onSaveInstanceState");outState.putString(EXTRA_TEST, "test");}@Overrideprotected void onRestoreInstanceState(Bundle savedInstanceState) {super.onRestoreInstanceState(savedInstanceState);String test = savedInstanceState.getString(EXTRA_TEST);Log.e(TAG, "[onRestoreInstanceState] restore extra_test:" + test);}
- 前台Activity——正在和用户交互的Activity,优先级最高。
- 可见前台但非前台Activity——比如Activity弹出了一个对话框,导致Activity可见,但是位于后台无法和用户直接交互。
- 后台Activity——已经被暂停的Activity,比如执行了onStop,优先级最低。
android:configChanges="orientation"
如果我们想指定多个值,可以用“|”连接起来,比如android:configChanges="orientation|keyboardHidden"。系统配置中所含的项目是非常多的,下面介绍每个项目的含义。如下表所示。
项目 | 含义 |
mcc | SIM卡唯一标识符IMSI(国际移动用户识别码)中的国家代码,由三位数字组成,中国为460。此项标识mcc代码发生了改变。 |
mnc | SIM卡唯一标识符IMSI(国际移动用户识别码)中的运营商代码,由两位数字组成,中国移动TD系统为00,中国联通为01,中国电信为03,此标识mnc发生改变 |
locale | 设备的本地位置发生了改变,一般指切换了语言系统 |
touchscreen | 触摸屏发生了改变,这个很费解,正常情况下无法发生,可以忽略它 |
keyboard | 键盘类型发生了改变,比如用户使用了外插键盘 |
keyboardHidden | 键盘的可访问性发生了改变,比如用户调出了键盘 |
navigation | 系统导航方式发生了改变,比如采用了轨迹球导航,这个有点非接,很难发生,可以忽略它 |
screenLayout | 屏幕布局发生了改变,很可能是用户激活了另外一个显示设备 |
fontScale | 系统字体缩放比例发生了改变,比如用户选择了一个新字号 |
uiMode | 用户界面模式发生了改变,比如是否开启了夜间模式(API8新添加) |
orientation | 屏幕方向发生了改变,这个是最常用了,比如旋转了手机屏幕 |
screenSize | 当屏幕尺寸信息发生了改变,当旋转设备屏幕时,屏幕尺寸会发生变化,这个选项比较特殊,它和编译选项有关,当编译选项中minSdkVersion和targetSdkVersion均低于13时,此选项不会导致Activity重启,否则会导致Activity重启(API13添加) |
smallestScreenSize | 设备的物理屏幕尺寸发生改变,这个项目和屏幕方向没有关系,仅仅表示在实际物理屏幕的尺寸改变的时候发生,比如用户切换到了外部的显示设备,这个选项和screenSize一样,当编译选项中的minSdkVersion和targetSdkVersion均低于13时,此选项不会导致Activity重启,否则会导致Activity重启(API13添加) |
layoutDirection | 当布局方向发生变化,这个属性用的比较少,正常情况下无法修改布局的layoutDirection |
<uses-sdk android:minSdkVersion="8"android:targetSdkVersion="19" />
<activity android:name=".MainActivity"android:configChanges="orientation|screenSize"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity>@Overridepublic void onConfigurationChanged(Configuration newConfig) {super.onConfigurationChanged(newConfig);Log.e(TAG, "[onConfigurationChanged] newOrientation:" + newConfig.orientation);}
由上面的日志可见,Activity的确没有重新创建,并且也没有调用onSaveInstanceState和onRestoreInstanceState来存储和恢复数据,取而代之的时系统调用了Activity的onConfigurationChanged方法,这个时候我们就可以做一些自己的处理了。
Activity的生命周期和启动模式--Activity的生命周期的全面分析相关推荐
- 安卓学习笔记06:Activity生命周期与启动模式
文章目录 零.学习目标 一.Activity生命周期 1.了解Activity生命周期 2.Activity生命周期简化图 (1)Activity存在与否 (2)Activity可见与否 (3)Act ...
- Activity详解Activity的使用步骤、生命周期及其启动模式、启动方法
开始我们先来回顾一下Activity的基础知识: Activity是应用程序的表现层,应用程序中可以包含多个Activity,它们之间可以相互跳转,来达到手机屏幕的切换.Activity通过View来 ...
- Activity生命周期和启动模式
Activity生命周期和启动模式 1. 典型情况下的生命周期分析 完整生存期:onCreate()-onDestory(),分别标识着Activity的创建和销毁,并且只可能有一次调用. 可见生存期 ...
- Android Activity的launchMode四种启动模式备忘
Android Activity的launchMode四种启动模式备忘 Android的Activity的启动模式有四种,在AndroidManifest.xml通过配置Activity的androi ...
- Android Activity的启动模式及对生命周期的影响
Activity的启动模式 官网解释链接 (tips:在阅读此文章前,应先对Activity生命周期掌握) 在每一个程序的main目录下有一个AndroidManifest.xml文件,这个文件是用来 ...
- Activity生命周期及启动模式详解
1.Activity生命周期 1.正常情况: (1) onCreate: 表示 Activty 正在被创建,这是 Activity 生命周期的第一个方法,可以做一些初始化的工作,比如:加载布局,绑定控 ...
- Android开发艺术探索笔记(一) Activity的生命周期和启动模式(1)
Activity作为Android开发中最常用的一个组件,是Android开发人员必须熟悉且掌握的重要内容.同时Activity也是在面试中经常被问到的一个方向.因此,掌握Activity的重要性也不 ...
- 第一章: Activity的生命周期和启动模式:
1.典型情况下的Activity的生命周期 1.1 所谓的典型情况下的Activity的生命周期,是指用户参与的情况下.即用户正常使用app应用的时候正常执行的activity的生命周期. 1.2 在 ...
- Android官方开发文档Training系列课程中文版:管理Activity的生命周期之启动一个Activity
原文地址 : http://android.xsoftlab.net/training/basics/activity-lifecycle/index.html 导言 用户通过导航退出或者返回应用的时 ...
最新文章
- python中label组件参数_Python tkinter(六) 标签(Label)组件的属性说明及示例
- labview曲线上两点画延长线_教你用直尺画各种几何图形
- TCP/IP详解--第五章
- 记一次接口性能优化实践总结:优化接口性能的八个建议
- Javascript中的关键字和保留字
- 【小工匠聊Modbus】05-数据类型
- django出现 CSRF cookie not set
- [代码阅读] ECS toString实现方法
- 软件生命周期管理研讨会有感
- SAP License:SAP传输错误所引起的系统崩溃事件反思
- 等高线生成地形_等高线一键变地形模型
- 数据库查询条件是list的集合
- Hadoop3.2.1 RPC通讯 一锅端
- mac系统下查看端口占用问题的解决方案
- 小白学NLP学习笔记-入门
- 05-SA8155 QNX I2C框架及代码分析
- 使用nexus-3.0.2-02-win64搭建自己的Maven nexus私服
- [高项]关键路径法VS关键链法
- 二、获取AccessToken
- php ppt转视频教程,如何制作ppt转换视频新手教程操作指南
热门文章
- L1 批判思维 - 独立思考- 破除思维误区 1.1为什么我们很难独立思考
- springcloud + nacos多环境联调、本地联调(即灰度版本)
- 旧电脑改装nas Linux,变废为宝 免费又好用的NAS软件推荐
- SpringBoot 整合Smart-doc生成接口文档
- 推荐一个博客工具——Boke宝贝
- 实验五——数据库设计实验
- 【GANs】Conditional Generative Adversarial Nets
- Mock.js和axios在vue-cli创建项目中的使用
- java trim 空指针_trim()空指针异常问题!
- 使用软路由实现智能Qos