【Android】Activity生命周期(亲测)
测试手机:Nexus 5 系统:4.4
一、测试
测试代码:
package com.example.androidalarm; import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.Button; public class MainActivity extends Activity {
Button addButton, cancelButton; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d("BigFootprint", "onCreate");
} @Override
public void onConfigurationChanged(Configuration newConfig) {
Log.d("BigFootprint", "onConfigurationChanged");
super.onConfigurationChanged(newConfig);
} @Override
public View onCreateView(String name, Context context, AttributeSet attrs) {
Log.d("BigFootprint", "onCreateView");
return super.onCreateView(name, context, attrs);
} @Override
protected void onDestroy() {
Log.d("BigFootprint", "onDestroy");
super.onDestroy();
} @Override
protected void onPause() {
Log.d("BigFootprint", "onPause");
super.onPause();
} @Override
protected void onRestart() {
Log.d("BigFootprint", "onRestart");
super.onRestart();
} @Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
Log.d("BigFootprint", "onRestoreInstanceState");
super.onRestoreInstanceState(savedInstanceState);
} @Override
protected void onResume() {
Log.d("BigFootprint", "onResume");
super.onResume();
} @Override
protected void onSaveInstanceState(Bundle outState) {
Log.d("BigFootprint", "onSaveInstanceState");
super.onSaveInstanceState(outState);
} @Override
protected void onStart() {
Log.d("BigFootprint", "onStart");
super.onStart();
} @Override
protected void onStop() {
Log.d("BigFootprint", "onStop");
super.onStop();
}
}
XML配置:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.androidalarm"
android:versionCode="1"
android:versionName="1.0" > <uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" /> <application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.androidalarm.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
以以上的代码运行,打开应用,LOG输出如下“

可以看到,打开Activity的时候,生命周期是符合文档描述的,但是onCreateView接口会被多次调用,所以最好不要在这边实例化数据。按下BACK键退出,LOG如下:

生命周期非常正常。当Activity显示的时候,屏幕暗掉,LOG如下:

红框中为多打印的3个生命周期过程,可以看到onSaveInstanceState的调用时机!亮起屏幕,LOG如下:

生命周期一如文档所说。如果按下Home键退出,则LOG如下:

可以看到,和屏幕暗掉的LOG完全一样。重新点击应用图标打开Activity,得到如下LOG:

这个时候并没有去OnCreate,而是调用了方法onRestart方法。
这时候切换屏幕(竖屏切为横屏):(备注:因为onCreateView调用次数太多,而且不是重点研究对象,后面去掉此处LOG)

可以看到切换的时候,生命周期又走了一遍,并且调用了onSaveInstanceState和onRestoreInstanceState方法用于保存和恢复状态。然后从横屏恢复为竖屏,LOG如下:

调用的生命周期过程完全和上面的切换完全一样。
接下来要试验的是,重新在XML文件中配置Activity。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.androidalarm"
android:versionCode="1"
android:versionName="1.0" > <uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" /> <uses-permission android:name="android.permission.CHANGE_CONFIGURATION"></uses-permission> <application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.androidalarm.MainActivity"
android:configChanges="orientation"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
多加了一个配置: android:configChanges="orientation"。并且需要添加permission。

这是竖屏——>横屏——>竖屏切换过程中打印的LOG,可以看到,和没有配置的时候完全一样。再配置如下:添加: android:configChanges="orientation|keyboardHidden"
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.androidalarm"
android:versionCode="1"
android:versionName="1.0" > <uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" /> <uses-permission android:name="android.permission.CHANGE_CONFIGURATION"></uses-permission> <application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.androidalarm.MainActivity"
android:configChanges="orientation|keyboardHidden"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
打印的LOG还是一样,接下来再配置:改成android:configChanges="orientation|screenSize", 切换横竖屏打印的LOG如下:

注意,这里也是竖屏——>横屏——>竖屏切换,每次切换只打印一行LOG。
二、结论
在网上看到很多的资料讲述生命周期,结论应该只有一个:生命周期会因为系统版本甚至因为定制等各种因素而各有差异。所以本文一开始就给出了测试环境。上面的测试只在一种环境下完成,不能代表所有系统和所有机型。读者如需了解问题,还应该在当前环境下自己去进行测试。但是由此依然可以得出一些结论:
1)onCreateView接口会被多次调用,在这个接口中的代码要好好考虑,实例化数据,加载资源的动作最好不要放在这个方法中;
2)如果不是程序主动关闭Activity(比如按下回退键),onPause()之后会调用onSaveInstanceState方法保存状态,此后恢复Activity,如果在这之间调用了onDestory,即Activity被意外销毁,会在onStart()和onResume()之间调用onRestoreInstanceState方法恢复状态,否则,会以onRestart->onStart()->onResume()的顺序重新打开Activity;
3)如果不配置Activity的configChanges或者配置没有起效果(注:如何起效果,视环境而定,最保险的方案目前是:android:configChanges="orientation|screenSize|keyboardHidden"),则在横竖屏切换的时候,会重新走一遍生命周期,否则,只会调用onConfigurationChanged方法;
补充一下关于configChanges的参数值解释:
| Value | Description |
| “mcc“ | The IMSI mobile country code (MCC) has changed — that is, a SIM hasbeen detected and updated the MCC.移动国家号码,由三位数字组成,每个国家都有自己独立的MCC,可以识别手机用户所属国家。 |
| “mnc“ | The IMSI mobile network code (MNC) has changed — that is, a SIM hasbeen detected and updated the MNC.移动网号,在一个国家或者地区中,用于区分手机用户的服务商。 |
| “locale“ | The locale has changed — for example, the user has selected a new language that text should be displayed in.用户所在地区发生变化。 |
| “touchscreen“ | The touchscreen has changed. (This should never normally happen.) |
| “keyboard“ | The keyboard type has changed — for example, the user has plugged in an external keyboard.键盘模式发生变化,例如:用户接入外部键盘输入。 |
| “keyboardHidden“ | The keyboard accessibility has changed — for example, the user has slid the keyboard out to expose it.用户打开手机硬件键盘 |
| “navigation“ | The navigation type has changed. (This should never normally happen.) |
| “orientation“ | The screen orientation has changed — that is, the user has rotated the device.设备旋转,横向显示和竖向显示模式切换。 |
| “fontScale“ | The font scaling factor has changed — that is, the user has selected a new global font size.全局字体大小缩放发生改变 |
根据这份解释,个人感觉其实系统是有BUG的,理论上configChanges=orientation这样的配置在设备旋转后就应该会去调用onConfigurationChanged方法,但实际上连亲生儿子也不遵循。
最后根据这次试验,总结一下Activity认为意外关闭的三种场景:
1)屏幕暗下去;
2)按下HOME键退出Activity;
3)横竖屏切换;
这三种情景都会导致Activity调用onSaveInstanceState去保存自己的状态以便于恢复。
【Android】Activity生命周期(亲测)的更多相关文章
- [转]: 两分钟彻底让你明白Android Activity生命周期(图文)!
转自:http://blog.csdn.net/android_tutor/article/details/5772285 大家好,今天给大家详解一下Android中Activity的生命周期,我在前 ...
- Android Activity生命周期
从android api文档摘抄出来的activity生命周期图如下: Activity有如下四种状态 a.活动状态 activity处于屏幕前台,获取到了焦点可以和用户进行交互,同一时刻只有一个a ...
- Android Activity生命周期详讲
管理 Activity 生命周期 通过实现回调方法管理 Activity 的生命周期对开发强大而又灵活的应用至关重要. Activity 的生命周期会直接受到 Activity 与其他 Activit ...
- android Activity生命周期(设备旋转、数据恢复等)与启动模式
1.Activity生命周期 接下来将介绍 Android Activity(四大组件之一) 的生命周期, 包含运行.暂停和停止三种状态,onCreate.onStart.onResume.o ...
- Android Activity生命周期以及Fragment生命周期的区别与分析
Android Fragment生命周期图: Activity生命周期图: 对照图: Fragment生命周期分析: 1. 当一个fragment被创建的时候,它会经历以下状态. onAttach() ...
- Android Activity 生命周期详解
学习android开发这么久对于activity的生命周期还没有仔细思考过,所以,我大致的把这些东西整理一下,希望通过这使自己理解的更透彻点吧! 首先看一下Activity生命周期图和它的的四个阶段 ...
- Android Activity生命周期概述
1. 官网介绍 2. Activity A 跳转 Acitvity B A:onPause --> B: onCreate --> B:onStart --> B: onResu ...
- xamarin Android activity生命周期详解
学Xamarin我为什么要写这样一篇关于Android 的activity生命周期的文章 已经学Xamarin android有一段时间了,现在想起当初Xamarin也走了不少的弯路.当然Xamari ...
- Android——Activity生命周期(转)
Activity生命周期 子曰:溫故而知新,可以為師矣.<論語> 学习技术也一样,对于技术文档或者经典的技术书籍来说,指望看一遍就完全掌握,那基本不大可能,所以我们需要经常回过头再仔细 ...
- Android Activity生命周期的几个问题
每一个Android开发者都应该知道,android系统有四个重要的基本组件,即Activity(活动).Service(服务).Broadcast Receive(广播接收器)和Content ...
随机推荐
- Web开发者的六个代码调试平台
代码调试平台是Web开发者进行开发.测试.分享.协作和交流的网络应用,它们支持实时的编辑.预览HTML.CSS和JavaScript的客户端代码.这些代码调试平台最值得称道的地方在于,它们中的大多数都 ...
- Jquery对文本框的值、字符串的验证;正则表达式字符串的验证
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Factory模式
使用new的Code都违反了DIP. 但是,依赖于稳定的具体类,是无害的.例如string. 另一方面,对于正在开发中的APP,很多具体类是易变的.此时应该依赖于抽象接口. Factory模式:只依赖 ...
- Java 线程 — JMM Java内存模型
JMM Java Memory Model,Java内存模型,属于语言级的内存模型 并发编程中存在的问题: 如何通信:用于线程之间交换信息.两种方式:共享内存,消息传递 如何同步:用于控制不同线程间操 ...
- 如何在windows7上安装启明星系统。
启明星系统提供多种安装方式.安装包里自带了setup.exe.每个程序的 install下有在线安装(例如请假应用程序为book,则默认为 http://localhost/book/install ...
- ASP.NET Web API中的参数绑定总结
ASP.NET Web API中的action参数类型可以分为简单类型和复杂类型. HttpResponseMessage Put(int id, Product item) id是int类型,是简单 ...
- Idea的live template参数中的预定义功能
Predefined Functions to Use in Live Template Variables Item Description annotated("annotation q ...
- C++ 记事本: 从历史说起
C 的简史 在谈论 C++ 的历史那么必须先得了解 C 的历史,那么我们先来看一段来自于 <<C专家编程>> 对 C 语言史前阶段的简单阐述: Ken Thompson(左), ...
- webService----wsimport调用方式
一.工具 1.myEclipse 2.jdk1.7 二.创建服务端 1.创建web Service Project 命名为TheService 2.创建class类ServiceHello.java, ...
- vim 多行注释消除注释,多行删除
进入可视化模式: Ctrl+v 继续进入编辑模式: shift+i 注释: shift+# 注释生效: ESC 取消注释 d 删除 选中全部字符块区域,使用方向键上下右: 然后,按一下d