购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

5.2 Activity的生命周期

5.2.1 Activity生命周期基础

Activity在Android中的运行是由Activity的回退栈来管理的,当前活动的Activity位于回退栈的栈顶,而回退栈中的其它Activity处于停止状态。在一个Activity中运行的过程中,会受到一些突发事件的影响。例如:当前展示的Activity被一个来点打断了,开启了另外一个Activity,从另一个Activity中返回了等等事件,为了处理这些突发事件,需要用到Activity的生命周期。

Activity在Android中的生命周期,下图做了完美的诠释:

从上图可以看出,Activity大致可以分为四种状态:

· 活动状态:当前Activity处于活动,被至于回退栈的顶端,处于前台用户可见,可以获得焦点。

· 暂停状态:其它Activity处于前台显示,但该Activity依然部分可见,只是不能获得焦点。

· 停止状态:其它Activity处于前台,该Activity完全不可见,无法获取焦点。

· 销毁状态:该Activity被销毁或者被系统回收。

在Activity的不同生命周期中,均有对应的生命周期方法被系统回调,熟悉这些方法的回调时机,对于开发Android应用非常的重要,这些方法如下:

· onCreate(Bundle savedStatus):创建Activity时被回调。

· onStart():启动Activity时被回调。

· onRestart():重新启动Activity时被回调。

· onPause():暂停Activity时被回调。

· onStop():停止Activity时被回调。

· onResume():恢复Activity时被回调。

· onDestroy():销毁Activity时被回调。

5.2.2 Activity生命周期转换过程

前面已经讲解了Activity的生命周期的基本知识,接下来使用实例来模拟Activity生命周期的触发与执行顺序。

首先创建一个新的Android项目,然后重写其中Activity的所有生命周期方法。

代码清单:\codes\05\02\ActivityLifecycleDemo\src\com\bookdemo\activitylifecycledemo \MainActivity.java

public class MainActivity extends Activity {
    private final static String TAG="main";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.i(TAG, "---onCreate方法被回调---");
    }

    @Override
    protected void onStart() {
        Log.i(TAG, "---onStart方法被回调---");
        super.onStart();
    }

    @Override
    protected void onRestart() {
        Log.i(TAG, "---onRestart方法被回调---");
        super.onRestart();
    }

    @Override
    protected void onResume() {
        Log.i(TAG, "---onResume方法被回调---");
        super.onResume();
    }

    @Override
    protected void onPause() {
        Log.i(TAG, "---onPause方法被回调---");
        super.onPause();
    }

    @Override
    protected void onStop() {
        Log.i(TAG, "---onStop方法被回调---");
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        Log.i(TAG, "---onDestroy方法被回调---");
        super.onDestroy();
    }    
}

在启动时候从LogCat里可以看到输出的日期:

当onResume()方法被回调之后,Activity处于运行状态。

再来演示从运行状态到暂停状态时生命周期方法的回调过程。在这个Activity中增加一个Button,为其打开一个窗口化的Activity。

代码清单:\codes\05\02\ActivityLifecycleDemo\src\com\bookdemo\activitylifecycledemo \MainActivity.java

btnOpenDialog = (Button) findViewById(R.id.btnOpenDialog);
    btnOpenDialog.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
        Intent intent = new Intent(MainActivity.this,
            DialogActivity.class);
        startActivity(intent);
        }
    })

对于一个Activity而言,如果要把它设置成一个窗口模式,在清单文件AndroidManifest.xml中配置Activity元素的时候,为其android:theme属性设置为:@android:style/Theme.Dialog,这是Android为我们提供的一个窗口主题,可以直接使用。

代码清单:\codes\05\02\ActivityLifecycleDemo\AndroidManifest.xml

<activity
    android:name="com.bookdemo.activitylifecycledemo.DialogActivity"
    android:theme="@android:style/Theme.Dialog" >
</activity>

在模拟器上运行会打开一个窗口,并显示一个关闭按钮,运行效果如下:

打开Activity窗口,再点击关闭按钮,LogCat输出日志如下图:

此时,原Activity从运行状态转换为暂停状态,先回调onPause()方法置为暂停状态,当关闭窗口后,重新获得前台显示,并可以获得焦点后,再回调Resume()方法重新置为运行状态。

接下来再来演示停止状态的回调方法执行过程,在Activity中再增加一个Button,响应其点击事件开启一个普通的Activity,开启时完全遮挡原Activity,使其运行在后台并不可见,然后在点击关闭按钮,退回到原Activity中。此时LogCat输出的日志信息如图:

从上图可以看出,当打开一个新的Activity时,原Activity会回调onPause()和onStop()方法,使原Activity置为暂停状态,当原Activity重新回到前台显示的时候,会回调onRestart()、onStart()、onResume()方法置原Activity为运行状态。

最后再来看看当一个Activity被退出销毁时,回调方法的调用顺序。在运行状态,点击回退按钮退出应用,观察LogCat输出的日志信息:

从上图退出应用的时候可以看出Activity销毁的时候,会先后调用onPause()、onStop()、onDestroy方法。

5.2.3 Activity生命周期简单应用

清楚了Activity各个不同的生命周期的转换过程,就明白了在什么场景下需要对哪些生命周期方法进行重写。通常对Activity生命周期应用最多的场景就是,对于非常重要的数据,可以通过重写onPause()方法在Activity被暂停之后进行数据持久化,然后重写onResume()方法,在Activity被恢复的同时也恢复数据。其实这也保证了非常良好的用户体验,用户在录入了一部分数据后被突发事件打断了,在解决完突发事件之后,回到原Activity还可以对之前录入的数据再次进行编辑。

下面通过一个实例来演示如何在Activity被销毁的时候保存数据,并且在Activity再次被创建的时候恢复数据。Android系统是支持屏幕方向切换的,也就是说Activity在横屏与竖屏的时候会需要不同的长宽比。在默认情况下,当屏幕方向进行切换的时候,Android的策略是先销毁当前Activity,然后再重新创建。当然这一点可以通过在清单文件AndroidManifest.xml中为这个Activity设置android:configChanges属性来改变,android:configChanges属性的设置在前面的章节中有讲到。

在屏幕方向切换时,Activity中有UI组件被录入数据,它是会被清空的,回到初始化的状态。如果需要保存UI组件被录入的数据,需要重写onPause()和onResume()方法,以方便在销毁的时候保存数据,在重新创建的时候恢复数据。

代码清单:\codes\05\02\ActivityLifecycleUseDemo\src\com\example\activitylifecycleusedemo\MainActivity.java

public class MainActivity extends Activity {
    private EditText etUsername;
    private String middleUsername;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        etUsername = (EditText) findViewById(R.id.etUsername);
    }

    @Override
    protected void onPause() {
        // 在Activity暂停的时候保存数据
        if (etUsername != null) {
            String username = etUsername.getText().toString();
            if (!TextUtils.isEmpty(username)) {
                middleUsername = username;
            }
        }
        super.onPause();
    }

    @Override
    protected void onResume() {
        // 在Activity恢复的时候恢复数据
        if (etUsername != null) {
            if (!TextUtils.isEmpty(middleUsername)) {
                etUsername.setText(middleUsername);
            }
        }
        super.onResume();
    }
}

在模拟器上,随意输入姓名,使用ctrl+F11快捷键,对模拟器进行屏幕方向的切换,可以看出,在Activity销毁之前保存了输入的姓名,在恢复之后同时也恢复了姓名。

这里是使用Activity类中的属性来保存数据,在实际项目中不能如此使用,因为很可能整个Activity都已经被销毁了,在其中的属性保存的数据自然也不存在了。所以一般而言,会使用数据持久化到内存中或者SD卡上,这部分内容会在后面的章节中讲到。屏幕方向的切换是一个特殊的例子,这里只对生命周期的讲解使用到了。 EeVPtlQCHyuMeXiD55PmK5qh9fiqbFtHNaNwVouESKzGdKwrupmxy9nEfJJTn3Aq

点击中间区域
呼出菜单
上一章
目录
下一章
×

打开