测试手机: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生命周期(亲测)的更多相关文章

  1. [转]: 两分钟彻底让你明白Android Activity生命周期(图文)!

    转自:http://blog.csdn.net/android_tutor/article/details/5772285 大家好,今天给大家详解一下Android中Activity的生命周期,我在前 ...

  2. Android Activity生命周期

    从android api文档摘抄出来的activity生命周期图如下: Activity有如下四种状态 a.活动状态  activity处于屏幕前台,获取到了焦点可以和用户进行交互,同一时刻只有一个a ...

  3. Android Activity生命周期详讲

    管理 Activity 生命周期 通过实现回调方法管理 Activity 的生命周期对开发强大而又灵活的应用至关重要. Activity 的生命周期会直接受到 Activity 与其他 Activit ...

  4. android Activity生命周期(设备旋转、数据恢复等)与启动模式

    1.Activity生命周期     接下来将介绍 Android Activity(四大组件之一) 的生命周期, 包含运行.暂停和停止三种状态,onCreate.onStart.onResume.o ...

  5. Android Activity生命周期以及Fragment生命周期的区别与分析

    Android Fragment生命周期图: Activity生命周期图: 对照图: Fragment生命周期分析: 1. 当一个fragment被创建的时候,它会经历以下状态. onAttach() ...

  6. Android Activity 生命周期详解

    学习android开发这么久对于activity的生命周期还没有仔细思考过,所以,我大致的把这些东西整理一下,希望通过这使自己理解的更透彻点吧! 首先看一下Activity生命周期图和它的的四个阶段 ...

  7. Android Activity生命周期概述

    1.  官网介绍 2.  Activity A 跳转 Acitvity B A:onPause --> B: onCreate --> B:onStart --> B: onResu ...

  8. xamarin Android activity生命周期详解

    学Xamarin我为什么要写这样一篇关于Android 的activity生命周期的文章 已经学Xamarin android有一段时间了,现在想起当初Xamarin也走了不少的弯路.当然Xamari ...

  9. Android——Activity生命周期(转)

    Activity生命周期   子曰:溫故而知新,可以為師矣.<論語> 学习技术也一样,对于技术文档或者经典的技术书籍来说,指望看一遍就完全掌握,那基本不大可能,所以我们需要经常回过头再仔细 ...

  10. Android Activity生命周期的几个问题

      每一个Android开发者都应该知道,android系统有四个重要的基本组件,即Activity(活动).Service(服务).Broadcast Receive(广播接收器)和Content ...

随机推荐

  1. 仿IOS 开关按钮

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  2. js图片时间翻转

    带素材 代码一: <!-- Author: XiaoWen Create a file: 2016-12-12 10:08:02 Last modified: 2016-12-12 11:30: ...

  3. Atitit.javascript 实现类的方式原理大总结

    Atitit.javascript 实现类的方式原理大总结 1. 实现类的式::构造方法方式:原型方式:构造方法+原型的混合方式 1 2. 原型方式(function mode)经典式..实现属性推荐 ...

  4. paip.java c++得到当前类,方法名称以及行号

    paip.java c++得到当前类,方法名称以及行号 作者Attilax 艾龙,  EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blog.csdn ...

  5. Leetcode 257 Binary Tree Paths 二叉树 DFS

    找到所有根到叶子的路径 深度优先搜索(DFS), 即二叉树的先序遍历. /** * Definition for a binary tree node. * struct TreeNode { * i ...

  6. 定义一个时钟类——Clock,它包括三个int型 成员变量分别表示时、分、秒,一个构造方法用于对三个成员变量(时、分、秒) 进行初始化,还有一个成员方法show()用于显示时钟对象的时间。其次,再定义 一个主类——TestClass,在主类的main方法中创建多个时钟类的对象,使用这 些对象调用方法show()来显示时钟的时间

    package java1; public class Clock { int hhh; int mmm; int sss; Clock(int h,int m,int s) { hhh=h; mmm ...

  7. informix 查看 当前锁表

    select username,sid,waiter,dbsname,tabname,rowidlk,keynum,type from sysmaster:syslocks l, sysmaster: ...

  8. Java中BigDecimal的8种舍入模式

    java.math.BigDecimal 不可变的.任意精度的有符号十进制数.BigDecimal 由任意精度的整数非标度值和32位的整数标度(scale)组成. 如果为零或正数,则标度是小数点后的位 ...

  9. 利用python自动清除Android工程中的多余资源

    我们直接在公司项目中使用,效果良好! 分享出脚本代码,希望对Android研发的同学有帮助. 提示,初学python,开发环境是Sublime Text 2,直接Ctrl+B的,其他环境下没调试过.应 ...

  10. puppy-language

    puppy language是一种解释型的结构化脚本语言. 项目地址: https://github.com/zlvb/PuppyLanguage 因为一直很忙,有段时间没去更新了,不过功能已经比较完 ...