深入剖析Android四大组件(一)——Activity生命周期详解

1.管理Activity的生命周期

无论是正在运行的Activity还是没有运行的Activity,它们都接受Android的框架管理,这使得Activity处于不同的生命周期。

①Activity的3种状态

通过回调方法来管理Activity的生命周期对于开发一个健壮并且灵活的应用程序是非常关键的。Activity的生命周期直接影响到它与其他Activity,任务以及栈的关系。

Activity存在3种状态,分别是resumed,paused和stopped。

resumed:指Activity在屏幕前台并且拥有用户焦点的状态,这个状态有时也称为“正在运行”

paused:指另一个Activity在屏幕前台并且拥有用户焦点的状态,但这个Activity仍然可见,即另一个Activity在前一个Activity之上,而前一个Activity又是可见的并且部分透明或者没有覆盖整个屏幕。一个处于paused状态的Activity是完全存活的(Activity对象村中被保留,它维护所有状态和成员信息,并依然依附窗口管理器),但是在内存极低时将被系统杀掉。

stopped:指前一个Activity被另一个Activity完全遮蔽(前一个Activity当前在后台中)。一个处于stopped状态的Activity仍然是存活的(这个Activity对象在内存中被保留,它维护所有状态和成员信息,但没有依附窗口管理器)。然而,它却不再显示给用户,并且在内存极低时会被系统杀掉。

如果一个Activity处于paused或stopped状态,那么系统会从内存中丢掉它,这可以通过调用它的finish()方法来实现,或者简单一点,通过杀掉它的进程来实现。当Activity重新打开(在它结束或者被杀掉之后)时,它就必须被重新创建。

②实现Activity的生命周期回调

当Activity发生状态转变时,它会通过回调方法来得到通知,我们可以重写所有这些回调方法完成适当的工作。当Activity状态发生改变时,Activity的框架包含每一个基本的生命周期方法,如下列代码所示:

@Override

public void onCreate(Bundle savedInstanceState){

//指示这个Activity正在被创建

super.onCreate(saveInstanceState);

//完成一些任务

}

@Override

protected void onStart(){

//这个Activity正在变为可见

super.onStart();

//完成一些任务

}

@Override

protected vodi onResume(){

//这个Activity已经变为可见

//现在是resumed状态

super.onResume();

//完成一些任务

}

@Override

oritected void onPause(){

//另一个Activity获得焦点而且当前的Activity失去焦点

//也就是当前Activity被另一个Activity部分或者全部覆盖

//当前Activity失去焦点的时候调用

//这个Activity现在处于paused状态

super.onPause();

//完成一些任务

}

@Override

protected void onStop(){

//这个Activity不再可见的时候调用

//当前Activity处于stopped状态

super.onStop();

//完成一些任务

}

@Override

protected void onDestory(){

//这个Activity已经被销毁

super.onDestory();

//完成一些任务

}

建议:通常,在实现这些生命周期方法时,必须先调用超类的实现(比如调用super.XXX)。综上所述,以上这些方法定义了Activity的整个生命周期。通过实现这些方法,我们就能监视Activity生命周期中的3个嵌套循环,具体如下所示。

Activity的整个生命周期发生在调用onCreate()和调用onDestory()之间。在onCreate()中,Activity应该设置“全局”状态(比如定义布局),并且在onDestory()中释放其余资源。例如,如果Activity有一个后台运行的线程从网络上下载数据,那么它应该在onCreate()中创建这个线程,并且在onDestory()停止该线程。

Activity的可见生命周期发生在调用onStart()和调用onStop()之间。在这个过程中,用户可以看到这个Activityd在屏幕中并且可以与之交互。例如,当一个新Activity启动并且前一个Activity不再可见的时候,onStop()就被调用了。在这两个方法之间,可以维护需要显示给用户的Activity资源。例如,可以在onStart()方法中注册一个广播接收器去监视影响UI的变化,当用户看不到显示的东西时,则在onStop()注销它。在Activity的整个生命周期中,当Activity在可见和隐藏之间切换时,系统就会多次调用onStart()和onStop()方法。

Activity的前台生命周期发生在调用onResume和调用onPause()之间。需要说明的是,在这期间,Activity在屏幕中所有其他Activity的前面并且拥有用户焦点。一般情况下,Activity可以被频繁转换。例如,当设备休眠或者显示一个对话框时,onPause()就会被调用。

对于以上知识,为了方便读者理解并理顺它们之间的内在关系,我们用一张图来直观地描述,如下图:

上图为Activity生命周期的演化过程

顺便也列出一张表,描述了在Activity的整个生命周期里定位的每一个回调方法以及其细节,以及回调方法完成后系统是否可以停止这个Activity等。

方法 描述 调用后是否可以被杀掉 下一步操作
onCreate()                                              当Activity第一次被创建时调用。此处可以做所有的一般静态设置,比如创建视图,绑定列表数据等。

如果状态被捕捉,并且此状态存在的话,这个方法传递一个包含这个Activity的前状态的Bundle对象。

onStart()
onRestart() Activity被停止后,再次启动之前调用。 onStart()
onStart() 在Activity对用户可见之前被调用。

如果这个Activity来到前台,那么下一步操作是调用OnResume()。

如果被隐藏,则下一步操作是调用onStop()。

onResume()或者onStop()
onResume()  在Activity开始与用户交互之前被调用。在这里,该Activity位于Activity栈顶,开始与用户交互。

需要注意的是,此时当前Activity处于resumed状态,这个状态下Activity是可见的。

onPause()
onPause() 当系统正在恢复另一个Activity的时候被调用。这个方法通常用于提交未保存的数据,停止动画以及可能 消耗CPU的事情等。这些应该高效地完成,因为下一个Activity在这个方法没有返回之前不会被运行。如果Activity回到前台,则下一步操作为调用onResume()。如果Activity变得不可见,则调用onStop(). onResume()或者onStop()
onStop() 当Activity对用户不再可见的时候调用。这会发生,是因为它正在被销毁或者另一个Activity(可以是已经存在的或者新的)被运行并且覆盖了它。

如果Activity恢复与用户交互,则下一步操作是调用onRestart(),如果这个Activity消失,则调用onDestory()。

onRestart()或者onDestory()
onDestory() 该Activity被销毁之前调用。这个Activity收到的最终调用。它可以是因为Activity正在结束(调用finish()),或者是因为心痛为保护空间而面临销毁这个Activity的实例而调用。可以通过isFinishing()方法区分这两种情况。

2.保存和协调Activity

在Activity切换状态的时候,可能需要保存一些中间状态,比如控件的选择状态等,以便当它重新被显示出来时仍可以恢复到之前推出的状态。

①保存Activity状态

当一个Activity被暂停或者停止的时候,它的状态被保留。因为当它被暂停或者停止的时候,Activity对象仍然驻留在内存中——所有有关它的成员变量和当前状态的信息仍然存在,因此,所有用户导致的Activity的变化就被保存在内存中。而当这个Activity返回到前台时(当它被恢复时),这些变化仍然在内存中。

然而,当系统为恢复内存而销毁一个Activity时,这个Activity对象也就被销毁了,此时系统就不能简单地恢复它并持有它的完整状态。取而代之的是,如果用户再次导航到这里,系统就必须重新创建这个Activity对象,但是用户不知道系统已经销毁了该Activity而现在又重新创建了它,因此,用户可能认为这个Activity就是之前的那个Activity。在这种情况下,我们可以通过实现一个附加的允许保存我们Activity状态信息的回调方法,而将关于Activity状态的重要信息保留下来,然后当系统重新创建这个Activity的时候,再去重新存储它。

保存Activity当前状态信心的回调方法是onSaveInstanceState()。系统在Activity被销毁之前调用此方法,并再传一个Bundle对象。这个Bundle对象可以存储Activity状态(以名称--值对的形式)信息,可以使用像putString()之类的方法。那么,如果系统停止掉Activity进程,并且用户又重新启动该Activity,那么系统进程会将这个Bundle对象传递给onCreate(),这样就可以恢复onSaveInstanceState()中保存的Activity状态了。如果没有为恢复的状态信息,那么传给onCreate()的Bundle对象则是null。

注意:因为保存应用程序状态不是必要的行为,所以不能确保onSaveInstanceState()在Activity被销毁之前调用(例如当用户因为明确关闭而使用BACK键离开该Activity时)。如果这个方法被调用,那么它将总是在onStop()并有可能在onPause()之前调用。

虽然如此,但即使你没有实现onSaveInstanceState()方法,也还是有一些Activity的状态通过Activity类默认实现的onSaveInstanceState()方法恢复。特别是,默认实现会为布局中的每一个视图调用onSaveInstanceState(),允许每一个视图提供它们自己要保存的信息。几乎每一个Android框架中的部件都会适当地实现这个方法。这样一来,当Activity被重新创建的时候,任何一个对于UI可见的变化都被自动保存和恢复。例如,EditText空间保存用户输入的所有文本,CheckBox空间保存它是否被选择。而我们需要做的只是为所有想要保存状态的空间提供一个唯一的ID(借助android:id属性)。

尽管onSaveInstanceState()的默认实现会保存这个Activity UI的有用信息,但是我们可能仍然需要重写它以便保存额外的信息。例如,我们可能需要保存在整个Activity生命周期中变化的成员变量的值。由于默认实现的onSaveInstanceState()帮助保存UI的状态,所以如果重写这个方法是为了保存额外的信息,那么就应该在做任何工作之 前先调用超类的onSaveInstanceState()方法。

注意:因为我们不能保证onSaveInstanceState()会被调用,所以使用它只可以记录Activity的瞬间状态,而不能用来保存持久数据。相反,当用户离开这个Activity时,应该用onPause()保存持久数据(例如那些应该保存到数据库中的数据)。

下图直观的展现了Android是如何保存这些状态的。

上图为Android保存这些状态的流程示意图

如果需要恢复保存的状态,应该都知道Activity的生命周期中有一个onCreate()方法中传递了一个Bundle对象,具体恢复的代码如下所示:

@Override

public void onCreate(Bundle saveInstanceState){

super.onCreate(saveInstanceState);

if(saveInstanceState!=null){

//获取你保存的状态信息

}

}

这样一来,当界面被创建的时候,Activity仍然能找到用户最后操作的数据。

需要注意的是,忧郁我们不能保证是否存在保存的状态,因此需要一个判断来鉴别if(saveInstanceState!=null)。

②协调Activity

当一个Activity启动另一个Activity的时候,它们都会经历各自的生命周期的改变。第一个Activity被暂停或停止(如果它仍然可见,就不会被停止)时,另一个Activity被创建,而这些Activity共享的数据被保存到磁盘或别的地方。

生命周期回调的顺序要很好地定义,尤其是当两个Activity在同一个过程中并且一个正在启动另一个的时候。下面给出了Activity A启动Activity B的顺序。

第一,Activity A执行onPause()方法。

第二,Activity B顺序执行onCreate(),onStart(),onResume()方法(Activity现在获得用户焦点)。

第三,如果Activity A在屏幕中不再可见,则它的onStop()方法就会被执行。

这个生命周期回调的序列允许我们管理从一个Activity到另一个Activity转变的信息。例如,假如必须要写数据库,则当第一个Activity停止的时候,那么紧跟着的Activity就可以读取那个停止了的Activity,这样的话,我们就应该在onPause()中而不是在onStop()中写数据库。

3.用实例说话

这个实例非常简单,它包含两个Activity,它们都实现了所有的生命周期回调接口,并且还实现了相关的Activity状态保存与状态恢复的回调方法。此外,我们还可以从一个Activity导航到另一个Activity上。具体的操作步骤如下所示。

①创建一个名为ActivityLife的工程,包名为helloworld.liyuanjing.example.com.activitylife。创建完成后,我们就在原有的基础上添加一个新类SecondActivity,它继承自Activity类。此时Android工程中就拥有两个Java代码文件,它们分别是MainActivity.java和SecondActivity.java。现在,这两个代码都实现生命周期的所有方法,并在各个方法中添加日志。添加日志的方法如下:

Log.e(TAG, message);

②将新增的类SecondActivity声明到AndroidManifest.xml文件中去,这一步非常重要。如果没有这一步,就无法启动SecondActivity。声明代码如下:

<activity android:name=".SecondActivity"></activity>

在AndroidManifest.xml中声明一个Activity有相当多的讲究,这里只做简单配置上去,从而使得我们的Activity可以正常启动,如需深入清单文件可以到http://blog.csdn.net/column/details/androidmanifest.html该专栏下一探究竟。

再者,为了实现从MainActivity上启动SecondActivity,我们需要在默认的布局文件(activity_main)中添加一个按钮。并且实现它的单击事件。在该事件中,启动SecondActivity。修改后的布局代码如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="vertical"

android:layout_width="match_parent"

android:layout_height="match_parent">

<TextView

android:id="@+id/content"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="@string/hello_world" />

<Button

android:id="@+id/mybut"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="To SecondActivity"/>

</LinearLayout>

修改后的MainActivity的代码如下:

public class MainActivity extends Activity {
    public static final String TAG="MainActivity";
    private Button mybut=null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.e(TAG, "MainActivity::onCreate()");
        this.mybut=(Button)findViewById(R.id.mybut);
        this.mybut.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(MainActivity.this,SecondActivity.class));
            }
        });
    }
    @Override
    protected void onStart() {
        super.onStart();
        Log.e(TAG, "MainActivity::onStart()");
    }
    @Override
    protected void onResume() {
        super.onResume();
        Log.e(TAG, "MainActivity::onResume()");
    }
    @Override
    protected void onPause() {
        super.onPause();
        Log.e(TAG, "MainActivity::onPause()");
    }
    @Override
    protected void onStop() {
        super.onStop();
        Log.e(TAG, "MainActivity::onStop()");
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.e(TAG, "MainActivity::onDestroy()");
    }
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Log.e(TAG, "MainActivity::onSaveInstanceState()");
    }
}

SecondActivity的代码如下:

public class SecondActivity extends Activity {
    public static final String TAG="SecondActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.e(TAG, "SecondActivity::onCreate()");
    }
    @Override
    protected void onResume() {
        super.onResume();
        Log.e(TAG, "SecondActivity::onResume()");
    }
    @Override
    protected void onStart() {
        super.onStart();
        Log.e(TAG, "SecondActivity::onStart()");
    }
    @Override
    protected void onPause() {
        super.onPause();
        Log.e(TAG, "SecondActivity::onPause()");
    }
    @Override
    protected void onStop() {
        super.onStop();
        Log.e(TAG, "SecondActivity::onStop()");
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.e(TAG, "SecondActivity::onDestroy()");
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Log.e(TAG, "SecondActivity::onSaveInstanceState()");
    }
}

③编译运行工程,注意观察日志。等到应用程序展现出来的时候,就可以观察到如下图所示的日志信息:

出现这样的界面就说明,一个Activity从启动到展示完成经历了从onCreate()到onStart(),在再到onResume的3个阶段。

④单击“导航”按钮,也就是布局文件那个按钮,启动SecondActivity,看看有什么样的日志输出,如下图:

此时,SecondActivity就呈现出来了,而原来的MainActivity则被SecondActivity覆盖掉而不再拥有用户焦点。因此,可得出下面的3个结论。

ⅠMainActivity的onPause()方法被调用。

ⅡSecondActivity将会经历与MainActivity一样的显示过程。

Ⅲ当完成SecondActivity的展现后,MainActivity保存的回调接口(onSaveInstanceState())就被调用。接着还会调用MainActivity的onStop()方法。

⑤按BACK键返回到原来的Activity,看看会发生什么?如下图:

从上图可知,发生了下面4件事情。

ⅠSecondActivity的onPause方法被调用,指示它即将被暂停。

Ⅱ由于MainActivity是曾经被创建的Activity,因此这里只调用了它的onStart()以及onResume()方法来完成Activity的重新展现。

ⅢSecondActivity完成了生命周期而被销毁。在这个过程中,它经历了停止和销毁两个生命周期。这也就意味着当需要它重新显示的时候,只能从重新创建开始了。

Ⅳ如果此次再次按下BACK键,则MainActivity也将被销毁。同样,它的onStop()以及onDestory()也会被依次调用。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-25 04:05:49

深入剖析Android四大组件(一)——Activity生命周期详解的相关文章

深入剖析Android四大组件(一)——Activity生命周期具体解释

1.管理Activity的生命周期 不管是正在执行的Activity还是没有执行的Activity,它们都接受Android的框架管理,这使得Activity处于不同的生命周期. ①Activity的3种状态 通过回调方法来管理Activity的生命周期对于开发一个健壮而且灵活的应用程序是很关键的. Activity的生命周期直接影响到它与其它Activity,任务以及栈的关系. Activity存在3种状态.各自是resumed,paused和stopped. ?resumed:指Activi

Android 四大组件之Activity生命周期

写这篇博文之前,已经对android有一定的了解和认识.这篇博文主要讲述android的Activity的生命周期,这是android开发者必须掌握的知识.android的Activity组件拥有7个生命周期:onCreate().onStart().onResume().onPause().onStop().onDestory().onReStart(). 这7个生命周期分别在4个特定阶段进行调用. 开始Activity:当Activity开始运行的时候依次执行3个生命周期:onCreate.

android四大组件之activity生命周期

activity在android里的作用是用于显示用户界面,即用户看到和进行操作的界面. androidManifest文件中含有如下过滤器的activity组件为程序默认启动类,当程序启动时系统自动调用它(程序启动时显示的首个页面). <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.inten

Android学习笔记:Activity生命周期详解

进行android的开发,必须深入了解Activity的生命周期.而对这个讲述最权威.最好的莫过于google的开发文档了. 本文的讲述主要是对 http://developer.android.com/training/basics/activity-lifecycle/index.html 的翻译,加上了个人的一些细节和补充. 一.总体介绍

Android学习笔记一:Android基本组件和Activity生命周期

View   View是创建UI的基础控件, Activity  一个应用程序可能包含多个Activity,用来在屏幕中展示用户数据或者编辑用户数据. Fragement  类似于Activity的子控件,一个Activity可以包含一个或多个Fragement. Intent   通常使用Intent来完成以下工作 1.广播消息(Broadcast);2.启动服务(Service):3.启动Activity(Launch Activity):4.显示网页或者联系人列表:5.拨号或者接听电话.

android --Activity生命周期详解

一. 再探Activity生命周期 为了研究activity的生命周期,简单测试代码如下. package com.example.testactivity; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.Menu; public class MainActivity extends Activity { private static fina

Android之Activity生命周期详解

Activity的生命周期方法: onCreate()--->onStart()--->onResume()--->onPause()--->onStop()--->onDestory() 单个Activity的三种状态:显示状态,不可见状态,销毁状态.1,activity创建到显示要调用前三个方法.2,点击后退键,做了两件事:(1)当前activity被销毁,调用后面三个周期方法.(2)栈中位于最顶部的Activity显示出来.3,onDestory()方法主要是当Acti

Activity生命周期详解

我们来看一下这一张经典的生命周期流程图: 相信不少朋友也已经看过这个流程图了,也基本了解了Activity生命周期的几个过程,我们就来说一说这几个过程. 1.启动Activity:系统会先调用onCreate方法,然后调用onStart方法,最后调用onResume,Activity进入运行状态. 2.当前Activity被其他Activity覆盖其上或被锁屏:系统会调用onPause方法,暂停当前Activity的执行. 3.当前Activity由被覆盖状态回到前台或解锁屏:系统会调用onRe

重识Activity——生命周期详解

1. 单个Activity生命周期*  显示状态--onCreate().onStart().onResume()* 隐藏状态--onPause():部分可见.onStop():隐藏,黑屏状态* 销毁--onDestroy() 2. 多个Activity生命周期交互* 第一个Activity启动--依次调用onCreate().onStart().onResume ()* 第二个Activity启动--第一个activity调用onPause (),第二个activity调用onCreate (