测试手机: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. C++ 表达式

    <C++ Primer 4th>读书摘要 C++ 提供了丰富的操作符,并定义操作数为内置类型时,这些操作符的含义.除此之外,C++ 还支持操作符重载,允许程序员自定义用于类类型时操作符的含 ...

  2. 【Oracle】Oracle锁表处理

    问题分析(1)锁的分析ORACLE里锁有以下几种模式:0:none1:null 空2:Row-S 行共享(RS):共享表锁,sub share3:Row-X 行独占(RX):用于行的修改,sub ex ...

  3. 使用Redis实现用户积分排行榜的教程

    转载于:http://www.itxuexiwang.com/a/shujukujishu/redis/2016/0216/129.html?1455808528 排行榜功能是一个很普遍的需求.使用 ...

  4. SSDB安装配置

    1.下载ssdb wget -O ssdb-master.zip https://codeload.github.com/ideawu/ssdb/zip/master 2.编译安装 unzip ssd ...

  5. Atitit org.eclipse.jdt 的ast 架构 Eclipse JDT API spec

    Atitit org.eclipse.jdt 的ast 架构 Eclipse JDT API spec 继承树1 Expression的子类1 获取子类2 继承树 Astnode>express ...

  6. iOS开发-图片高斯模糊效果

    iOS开发的时候有的时候需要将图片设置模糊,或者通过点击下拉方法,去除模糊,一切都是为了应用更受用户欢迎,iOS7之后半透明模糊效果得到大范围使用的比较大,现在也可以看到很多应用局部用到了图片模糊效果 ...

  7. js实现点击一个按钮进行两种状态的切换(toggle)

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

  8. c#中的事件

    之前的博客讲到委托,委托本质上是将方法作为方法的参数传给方法.实际开发中,实现某个功能的的代码通常会封装成一个类,本例中字符串处理封装成MyStringProc类, 代码如下: namespace D ...

  9. Spark核心—RDD初探

    本文目的     最近在使用Spark进行数据清理的相关工作,初次使用Spark时,遇到了一些挑(da)战(ken).感觉需要记录点什么,才对得起自己.下面的内容主要是关于Spark核心-RDD的相关 ...

  10. LINUX系统下添加映射存储LUN

    LINUX系统下添加映射存储LUN(无需重启) 背景:Oracle rac环境 添加新实例,重新划分存储空间,从存储映射新的LUN. 问题:映射后,linux操作系统无法识别新的LUN,不能重启系统, ...