测试手机: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. nested exception is org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'beans'.

    1缺少jar包 2spring配置文件里http://www.springframework.org/schema/beans/spring-beans-3.2.xsd的版本与实际jar包不一致

  2. 基于iscroll.js实现下拉刷新和上拉加载特效

    现在已经不是纯Android独霸天下的时代了,H5嵌入Android的Hybrid混合开发是大势所趋.今天给大家带来的就是移动端中常见的"上拉刷新,下拉加载"特效,这个特效将会基于 ...

  3. celery简单入门

    写作背景介绍 最近在做后台图像处理,需要使用到celery这个异步任务框架.但是使用的时候遇到很多技术问题,为了方便日后再遇到相似问题时能够快速解决.写下这篇文章也希望能够帮助共同奋战在同一战线的程序 ...

  4. atitit.ajax 最佳实践跟框架选型 o99

    atitit.ajax 最佳实践跟框架选型 1. 选型框架dwr/dwr3 跟jq 1 2. DWR方便的地方分为两个地方. 1 3. dwr 优点: 1 4. 缺点: 2 5. 根jq的区别 2 1 ...

  5. (谷歌浏览器等)解决css中点击input输入框时出现外边框方法【outline:medium;】

    问题:在使用谷歌浏览器,360浏览器时,点击input输入框会出现带颜色的外边框,如下图所示:

  6. Unreal Engine 4官网教程

    编辑器纵览 https://www.unrealengine.com/zh-CN/blog/editor-overview 虚幻编辑器UI布局概述 https://www.unrealengine.c ...

  7. mysql 创建用户并赋予权限

    mysql> create user 'zhangsan'@'localhost' identified by '123456'; Query OK, 0 rows affected (0.00 ...

  8. HBase、Redis、MongoDB、Couchbase、LevelDB主流 NoSQL 数据库的对比

    最近小组准备启动一个 node 开源项目,从前端亲和力.大数据下的IO性能.可扩展性几点入手挑选了 NoSql 数据库,但具体使用哪一款产品还需要做一次选型. 我们最终把选项范围缩窄在 HBase.R ...

  9. shell脚本编写方法

    shell脚本编写就如同一门语言,涉及到运行环境.基本语法.变量定义.函数.参数(系统参数).条件判定.执行流程控制 等等问题. 本文就以下几个方面进行描述: 运行环境: shell  shebang ...

  10. Gradle自定义你的BuildConfig

    BuildConfig.DEBUG 首先在Gradle脚本中默认的debug和release两种模式BuildCondig.DEBUG字段分别为true和false,而且不可更改.该字段编译后自动生成 ...