Activity的生命周期

摘要:
今天对于Activity的生命周期又有了一点深入的理解。因此,对应的生命周期如下图:也就是说在发生意外时,系统会自动调用onSaveInstanceState方法来保存数据,在需要的时候再会重新创建出这个活动,然后自动调用onRestoreInstanceState方法来恢复数据。上面列出的两种意外情况下的活动的生命周期是一样的,都是如上图所示。下面再修改其MainActivity代码,如下:1publicclassMainActivityextendsActionBarActivity{23privatestaticfinalStringTag="MainActivity";45@Override6protectedvoidonCreate{7super.onCreate;8setContentView;910if(savedInstanceState!

今天对于Activity的生命周期又有了一点深入的理解。做个总结吧。

一、正常情况下的生命周期

什么叫正常情况下的生命周期呢?也就是我们经常了解的一个活动的正常的生命流程。不用过度解释,

总结如下:

(1)onCreate()方法

活动第一次创建时被调用。

(2)onStart()

活动由不可见变为可见的时候调用

(3)onResume()

当活动准备开始与用户交互时会触发该方法,一般只会在需要执行以下的操作时才重写该事件:

l 开始动画

l 开始监听GPS更新

l 显示一些相关的提示和对话框

l 注册广播监听

4onPause()

系统准备去启动或者恢复另外一个活动的时候调用。或者当活动被切换到后台时将触发该方法,一般我们需要在该事件做如下的事情:

l 保存用户未提交的数据

l 关闭或清除引用的资源

l 注销广播

l 如果存在正在显示的提示或者对话框,则必须利用.Dismiss()进行清除。

5onStop()

当该活动完全不可见的时候被调用。一般会由以下原因触发:

l 当一个新的活动打开,并覆盖该活动时

l 一个已存在的活动切换到前台时

l 活动被销毁时

OnStop不是每次都会被执行,如果内存低下时,系统将不会执行该事件,而是直接关闭该应用,所以大家在OnPause事件中就要保存好所以的参数等等。而不能依赖该事件。

(6)onDestroy()

活动销毁之前被调用

7onRestart()

当活动由停止状态变为运行状态时被调用。即当用户通过Home按钮将该用户切换到后台,并在之后又打开该应用则会触发该事件。一般也很少重写该方法。

贴一张大家都知道的流程图吧,如下:

Activity的生命周期第1张

Activity的生命周期第2张

需要极其注意的是:在onPause中执行的操作不能太耗时!

二、异常情况下活动的生命周期

这个是重点要说的!什么是异常情况呢?不好说,比如因为资源相关的配置发生改变或者系统内存不足时,活动就

会被杀死。这就属于异常情况,总之一句话:活动被异常终止!最常见的就是下面的两种情况:

(1)横屏或者竖屏切换时。此时因为切换之间系统要对活动中的布局里面的图片进行更换(比如你可能会准备同样的两张

图片,不同像素宽高,分别对应于横屏或者竖屏的情况),此时就会导致在切换时,活动被瞬间杀死又被瞬间重建!

(2)因为系统内存不足,活动被回收时。

发生意外终止,系统做出的对策就是会将活动中的数据进行自动保存,然后再需要的时候再将活动创建出来恢复数据。

因此,对应的生命周期如下图:

Activity的生命周期第3张

也就是说在发生意外时,系统会自动调用onSaveInstanceState方法来保存数据,在需要的时候再会重新创建出这个活动,

然后自动调用onRestoreInstanceState方法来恢复数据。你可能会有疑问,一个活动中可能有一个TextView,还有一个按钮,

可能还有其他的,那么当活动意外终止,怎么来控制保存这些控件的数据呢?其实任何一个view都重写了onSaveInstanceState

和onRestoreInstanceState方法,你可以翻看源码,看看发生意外时,每一个view都会自动保存什么。这里不再多说。

上面列出的两种意外情况下的活动的生命周期是一样的,都是如上图所示。系统内存不足,不好模拟。但是横屏和竖屏

比较好模拟。下面我们通过一个实际例子,来看看是不是真的如上面所述的那样。

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

新建一个项目。修改其Manifest文件,加入横竖和竖屏切换的感应,如下:

 <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:screenOrientation="sensor"
            >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

上面只贴出了修改的那段代码,黄色部分就是加入的自动切换横屏和竖屏的功能。

下面再修改其MainActivity代码,如下:

1 public class MainActivity extends ActionBarActivity {
2 
3 private static final String Tag = "MainActivity";
4 
5 @Override
6 protected void onCreate(Bundle savedInstanceState) {
7 super.onCreate(savedInstanceState);
8 setContentView(R.layout.activity_main);
9 
10 if(savedInstanceState != null)
11 {
12 String t = savedInstanceState.getString("save_test");
13 Log.e(Tag,t+"   "+"onCreate");
14 }
15 
16 }
17 
18 @Override
19 protected void onSaveInstanceState(Bundle outState) {
20 super.onSaveInstanceState(outState);
21 
22 String t = "save me  ";
23 Log.e(Tag,t+"onSaveInstanceState");
24 outState.putString("save_test",t);
25 }
26 
27 @Override
28 protected void onRestoreInstanceState(Bundle savedInstanceState) {
29 super.onRestoreInstanceState(savedInstanceState);
30 
31 String t = savedInstanceState.getString("save_test");
32 Log.e(Tag,t+"    "+"onRestoreInstanceState");
33 }
34 
35  
36 }

代码中重写了onSaveInstanceState和onResoreInstanceState方法,然后就在各个方法中打印标签。

下面运行一下程序,做如下的操作:

Activity的生命周期第4张

也就是控制手机,做了一个横竖和竖屏的切换。我们来看一下打印结果,如下:

Activity的生命周期第5张

通过打印结果,就会发现在横屏和竖屏切换时,确实是调用了保存数据和恢复数据的那些方法。而从再一次

调用了onCreate方法,就知道活动被重建了。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++

接着上面的分析,有没有方法让在横竖和竖屏切换时,不要重新创建活动呢??当然是肯定的。

其实很简单,只要在Manifest文件中加入configChanges属性即可。也就是当检测到confiChanges指定

的属性发生改变时,也不会再去重新创建活动了

下面我们就修改代码,来测试一下。首先修改Manifest中的代码,如下:

 <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:screenOrientation="sensor"
            android:configChanges="orientation|screenSize">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

可以看到,添加了一句(即黄色部分),即检测到方向发生改变或者屏幕的size改变,也不去重新创建活动。

这针对的就是横屏和竖屏的切换。

然后修改MainActivity中的代码,如下:

1 public class MainActivity extendsActionBarActivity {
2 
3     private static final String Tag = "MainActivity";
4 
5 @Override
6     protected voidonCreate(Bundle savedInstanceState) {
7         super.onCreate(savedInstanceState);
8 setContentView(R.layout.activity_main);
9 
10         if(savedInstanceState != null)
11 {
12             String t = savedInstanceState.getString("save_test");
13             Log.e(Tag,t+"   "+"onCreate");
14 }
15 
16 }
17 
18 @Override
19     protected voidonSaveInstanceState(Bundle outState) {
20         super.onSaveInstanceState(outState);
21 
22         String t = "save me  ";
23         Log.e(Tag,t+"onSaveInstanceState");
24         outState.putString("save_test",t);
25 }
26 
27 @Override
28     protected voidonRestoreInstanceState(Bundle savedInstanceState) {
29         super.onRestoreInstanceState(savedInstanceState);
30 
31         String t = savedInstanceState.getString("save_test");
32         Log.e(Tag,t+"    "+"onRestoreInstanceState");
33 }
34 
35 @Override
36     public voidonConfigurationChanged(Configuration newConfig) {
37         super.onConfigurationChanged(newConfig);
38         Log.e(Tag,"onConfigurationChanged");
39 }
40 }

黄色部分是我们新增加的代码。然后运行程序,依然做一个横屏竖屏的切换操作,打印结果如下:

Activity的生命周期第6张

我们这次只有onConfiguration这一个方法被调用。onSaveInstanceState方法和onRestoreInstanceState方法

都没有被调用,onCreate方法也没有,即没有再重新创建活动了。这提示我们,如果在横竖屏切换过程中,还想做一些

逻辑操作的话,可以放在onConfiguration方法中。

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

总结:(1)系统只在异常终止了Activity时,才会调用onSaveInstanceState和onRestoreInstanceState方法

来恢复数据。因此我们可以重写这两个方法来防止活动被出现意外终止时,数据发生丢失。

(2)如果使用了在Manifest文件中加入configChanges属性来监测发生变化时不再重新创建活动,那么

onConfiguration方法会被自动回调,我们可以在这里实现相关逻辑。

(3)就是上面的两张图,一个正常活动生命周期的图,一个异常下活动生命周期的图。

免责声明:文章转载自《Activity的生命周期》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇把FlvDownloader重构了一下PE444下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

3--Java NIO基础1

一、NIO概述 1. BIO带来的挑战 BIO即堵塞式I/O,数据在写入或读取时都有可能堵塞,一旦有堵塞,线程将失去CPU的使用权,性能较差。 2. NIO工作机制 Java NIO由Channel、Buffer、Selector三个核心组成,NIO框架类结构图如下: 其中,Buffer主要负责存取数据,Channel用于数据传输,获取数据,然后流入Bu...

WPF: 在ListView中添加Checkbox列表

描述:ListView是WPF中动态绑定工具的数据容器,本文实现了一个在ListView中显示的供用户选择的列表项目,并且控制列表中选择的项目数量,即实现单选。 XAML中创建ListView,代码如下: <ListView x:Name="listView_LineOfBusiness" Width="280" Height="220">...

动态将ASPX生成HTML网页并将网页导出PDF

1.首先要找到wnvhtmlconvert.dll这个文件,并引入项目中。 2.Server.Execute("pos.aspx?id=" + ids); 执行相应的aspx网页 3.pos.aspx网页中有这样的一个方法,此方法用来生成html页面 protected override void Render(HtmlTextWriter writer)...

C# 文件操作详解(一)File类

C#对文件的操作相当方便,主要涉及到四个类:File、FileInfo、Directory、DirectoryInfo,前两个提供了针对文件的操作,后两个提供了针对目录的操作,类图关系如下: 图1:类图 下面通过实例来看下每个类的使用。 一、File类 File中提供了许多的静态方法,使用这些静态方法我们可以方便的对文件进行读写查等基本操作。 1、读文件...

读《Effect Java中文版》

读《Effect Java中文版》 译者序 序 前言 第1章引言 1   第2章创建和销毁对象 4 第1条:考虑用静态工厂方法代替构造函数 4 第2条:使用私有构造函数强化singleton属性 8 第3条:通过私有构造函数强化不可实例化的能力 10 第4条:避免创建重复的对象 11 第5条:消除过期的对象引用 14 第6条:避免使用终结函数 17  ...

Java若不为空则取其值的lambda表达式

  原本的写法是: Map<String, Object> map = new HashMap<>(); String text = ""; if(map.get("text")!=null){ text = map.get("text").toString().trim(); } System.out.prin...