Activiy生命周期注意点

本文详细介绍了Android中Activity的生命周期,包括关键回调方法如onPause(), onResume(), onStop(), onRestart(), onStart() 和 onDestroy()的作用及使用场景。此外还讨论了如何通过onSaveInstanceState()和onRestoreInstanceState()来保存和恢复Activity的状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.onPause()

(1)当半透明Activity阻挡您的Activity时,系统会调用 onPause() 并且Activity会在“暂停”状态下等待 。 如果用户在Activity仍然处于暂停状态时返回Activity,则系统会调用 onResume()。

(2)当系统为您的Activity调用 onPause() 时,它从技术角度看意味着您的Activity仍然处于部分可见状态,但往往说明用户即将离开Activity并且它很快就要进入“停止”状态。您通常应使用 onPause() 回调:

1>停止动画或其他可能消耗 CPU 的进行之中的操作。

2>提交未保存的更改,但仅当用户离开时希望永久性保存此类更改(比如电子邮件草稿)。

3>释放系统资源,比如广播接收器、传感器手柄(比如 GPS) 或当您的Activity暂停且用户不需要它们时仍然可能影响电池寿命的任何其他资源。

例如,如果您的应用使用 Camera, onPause() 方法是释放它的好位置。

@Override

public void onPause() {

   super.onPause();  // Always call thesuperclass method first

    // Releasethe Camera because we don't need it when paused

    // andother activities might need to use it.

    if(mCamera != null) {

       mCamera.release()

       mCamera = null;

    }

}

(3)一般情况下,您不得使用 onPause() 永久性存储用户更改(比如输入表格的个人信息)。 只有在您确定用户希望自动保存这些更改的情况(比如,电子邮件草稿)下,才能在 onPause()中永久性存储用户更改。但您应避免在 onPause() 期间执行 CPU 密集型工作,比如向数据库写入信息,因为这会拖慢向下一Activity过渡的过程(您应改为在 onStop()期间执行高负载关机操作。

(4)当您的Activity暂停时,Activity 实例将驻留在内存中并且在Activity继续时被再次调用。您无需重新初始化在执行任何导致进入“OnResume()”状态的回调方法期间创建的组件。

2.onResume()

每当您的Activity进入前台时系统便会调用此方法,包括它初次创建之时。同样地,您应实现onResume() 初始化您在 onPause() 期间释放的组件并且执行每当Activity进入“继续”状态时必须进行的任何其他初始化操作(比如开始动画和初始化只在Activity具有用户焦点时使用的组件)。onResume() 的以下示例对应于以上的 onPause() 示例,因此它初始化Activity暂停时释放的照相机。

@Override

publicvoid onResume() {

    super.onResume();  // Always call the superclass method first

    // Get the Camera instance as the activityachieves full user focus

    if (mCamera == null) {

        initializeCamera(); // Local method tohandle camera init

    }

}

3.onStop() 和 onRestart()

(1)正确停止和重新开始Activity是Activity生命周期中的重要过程,其可确保您的用户知晓应用始终保持Activity状态并且不会丢失进度。有几种Activity停止和重新开始的关键场景:

1>用户打开“最近应用”窗口并从您的应用切换到另一个应用。当前位于前台的您的应用中的Activity将停止。 如果用户从主屏幕启动器图标或“最近应用”窗口返回到您的应用,Activity会重新开始。

2>用户在您的应用中执行开始新Activity的操作。当第二个Activity创建好后,当前Activity便停止。 如果用户之后按了返回按钮,第一个Activity会重新开始。

3>用户在其手机上使用您的应用的同时接听来电。

(2)因为系统在停止时会将您的 Activity 实例保留在系统内存中,您根本无需实onStop() 和 onRestart()或甚至onStart() 方法。对于大多数相对简单的Activity而言, Activity将停止并重新开始,并且您可能只需使用 onPause() 暂停正在进行的操作,

并从系统资源断开连接。

(3)用户离开Activity时,系统会调用 onStop() 停止Activity。 如果用户在Activity停止时返回,系统会调用 onRestart() ,紧接着调用 onStart() 和 onResume() 。 注意:无论什么场景导致Activity停止,系统始终会在调用 onStop() 之前调用onPause()。

(4)onStop()

当您的Activity收到 onStop() 方法的调用时,它不再可见,并且应释放几乎所有用户不使用时不需要的资源。一旦您的Activity停止,如果需要恢复系统内存,系统可能会销毁该实例。在极端情况下,系统可能会仅终止应用进程,而不会调用Activity的最终 onDestroy() 回调,因此您使用 onStop() 释放可能泄露内存的资源非常重要。尽管 onPause() 方法在 onStop()之前调用,您应使用 onStop() 执行更大、占用更多 CPU 的关闭操作,比如向数据库写入信息。

例如,此处是将草稿笔记内容保存在永久存储中的 onStop() 的实现:

@Override

protectedvoid onStop() {

    super.onStop();  // Always call the superclass method first

    // Save the note's current draft, becausethe activity is stopping

    // and we want to be sure the current noteprogress isn't lost.

    ContentValues values = new ContentValues();

    values.put(NotePad.Notes.COLUMN_NAME_NOTE,getCurrentNoteText());

    values.put(NotePad.Notes.COLUMN_NAME_TITLE,getCurrentNoteTitle());

    getContentResolver().update(

            mUri,    // The URI for the note to update.

            values, // The map of column names and new values to apply to them.

            null,    // No SELECT criteria are used.

            null     // No WHERE columns are used.

            );

}

当您的Activity停止时, Activity 对象将驻留在内存中并在Activity继续时被再次调用。 您无需重新初始化在任何导致进入“继续”状态的回调方法过程中创建的组件。 系统还会在布局中跟踪每个 View 的当前状态,如果用户在 EditText 小工具中输入文本,该内容会保留,因此您无需保存即可恢复它。

4.onStart() / onRestart()

当您的Activity从停止状态返回前台时,它会接收对 onRestart() 的调用。系统还会在每次您的Activity变为可见时调用 onStart() 方法(无论是正重新开始还是初次创建)。但是,只会在Activity从停止状态继续时调用 onRestart() 方法,因此您可以使用它执行只有在Activity之前停止但未销毁的情况下可能必须执行的特殊恢复工作。应用需要使用 onRestart() 恢复Activity状态的情况并不常见,因此没有适用于一般应用群体的任何方法指导原则。但是,因为您的 onStop() 方法应基本清理所有Activity的资源,您将需要在Activity重新开始时重新实例化它们。但是,您还需要在您的Activity初次创建时重新实例化它们(没有Activity的现有实例)。出于此原因,您应经常使用 onStart() 回调方法作为 onStop() 方法的对应部分,因为系统会在它创建您的Activity以及从停止状态重新开始Activity时调用 onStart() 。

例如,因为用户可能在回到它之前已离开应用很长时间, onStart() 方法是确认所需系统功能已启动的理想选择:

@Override

protectedvoid onStart() {

    super.onStart();  // Always call the superclass method first

    // The activity is either being restartedor started for the first time

    // so this is where we should make surethat GPS is enabled

    LocationManager locationManager =

    (LocationManager)getSystemService(Context.LOCATION_SERVICE);

    boolean gpsEnabled =locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);

    if (!gpsEnabled) {

        // Create a dialog here that requeststhe user to enable GPS, and use an intent

        // with theandroid.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS action

        // to take the user to the Settingsscreen to enable GPS when they click "OK"

    }

}

@Override

protectedvoid onRestart() {

    super.onRestart();  // Always call the superclass method first

    // Activity being restarted from stoppedstate

}

当系统销毁您的Activity时,它会调用您的 Activity 的 onDestroy() 方法。因为您通常应已使用 onStop() 释放大多数您的资源,到您接收对 onDestroy() 的调用时,大多数应用无需做太多操作。此方法是您清理可导致内存泄露的资源的最后一种方法,因

此您应确保其他线程被销毁且其他长期运行的操作(比如方法跟踪)也会停止。

5.Recreating an Activity

如果Activity当前被停止或长期未使用,或者前台Activity需要更多资源以致系统必须关闭后台进程恢复内存,系统也可能会销毁Activity。

当您的Activity因用户按了返回或Activity自行完成而被销毁时,系统的 Activity 实例概念将永久消失,因为行为指示不再需要Activity。 但是,如果系统因系统局限性(而非正常应用行为)而销毁Activity,尽管 Activity 实际实例已不在,系统会记住其存在,这样,如果用户导航回实例,系统会使用描述Activity被销毁时状态的一组已保存数据创建Activity的新实例。 系统用于恢复先前状态的已保存数据被称为“实例状态”,并且是 Bundle 对象中存储的键值对集合。注意:每次用户旋转屏幕时,您的Activity将被销毁并重新创建。 当屏幕方向变化时,系统会销毁并重新创建前台Activity,因为屏幕配置已更改并且您的Activity可能需要加载备用资源(比如布局)。为了 Android 系统恢复Activity中视图的状态,每个视图必须具有 android:id 属性提供的唯一 ID。

要保存有关Activity状态的其他数据,您必须替代 onSaveInstanceState() 回调方法。当用户要离开Activity并在Activity意外销毁时向其传递将保存的 Bundle 对象时,系统会调用此方法。如果系统必须稍后重新创建Activity实例,它会将相同的 Bundle 对象同时传递给 onRestoreInstanceState() 和 onCreate() 方法。当系统开始停止您的Activity时,它会 调onSaveInstanceState(),因此,您可以指定您希望在 Activity 实例必须重新创建时保存的额外状态数据。如果Activity被销毁且必须重新创建相同的实例,系统将在中定义的状态数据同时传递给 onCreate() 方法和onRestoreInstanceState() 方法。

(1)  保存Activity状态

当您的Activity开始停止时,系统会调用 onSaveInstanceState() 以便您的Activity可以保存带有键值对集合的状态信息。此方法的默认实现保存有关Activity视图层次的状态信息,例如 EditText 小工具中的文本或ListView 的滚动位置。要保存Activity的更多状态信息,您必须实现 onSaveInstanceState() 并将键值对添加至 Bundle 对象。 例如:

static final String STATE_SCORE ="playerScore";

static final String STATE_LEVEL ="playerLevel";

...

@Override

public voidonSaveInstanceState(Bundle savedInstanceState) {

   // Save the user's current game state

   savedInstanceState.putInt(STATE_SCORE, mCurrentScore);

   savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel);

   // Always call the superclass so it can save the view hierarchy state

   super.onSaveInstanceState(savedInstanceState);

}

注意:始终调用onSaveInstanceState() 的超类实现,以便默认实现可以保存视图层次的状态。

(2)  恢复Activity状态

当您的Activity在先前销毁之后重新创建时,您可以从系统向Activity传递的 Bundle 恢复已保存的状态。onCreate() 和onRestoreInstanceState() 回调方法均接收包含实例状态信息的相同 Bundle。因为无论系统正在创建Activity的新实例还是重新创建先前的实例,都会调用 onCreate() 方法,因此您必须在尝试读取它之前检查状态 Bundle 是否为 null。 如果为 null,则系统将创建Activity的新实例,而不是恢复已销毁的先前实例。

例如,此处显示您如何可以在onCreate() 中恢复一些状态数据:

@Override

protected void onCreate(BundlesavedInstanceState) {

   super.onCreate(savedInstanceState); // Always call the superclass first

   // Check whether we're recreating a previously destroyed instance

   if (savedInstanceState != null) {

        // Restore value of members from savedstate

        mCurrentScore =savedInstanceState.getInt(STATE_SCORE);

        mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);

   } else {

        // Probably initialize members withdefault values for a new instance

   }

   ...

}

您可以选择实现系统在onStart() 方法之后调用的onRestoreInstanceState() ,而不是在onCreate() 期间恢复状态。 系统只在存在要恢复的已保存状态时调用 onRestoreInstanceState() ,因此您无需检查 Bundle 是否为 null:

public voidonRestoreInstanceState(Bundle savedInstanceState) {

   // Always call the superclass so it can restore the view hierarchy

   super.onRestoreInstanceState(savedInstanceState);

 

   // Restore state members from saved instance

   mCurrentScore = savedInstanceState.getInt(STATE_SCORE);

   mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);

}

注意:始终调用onSaveInstanceState() 的超类实现,以便默认实现可以恢复视图层次的状态。

(3)onSaveInstanceState:

1>在Activity被覆盖或退居后台之后,系统资源不足将其杀死,此方法会被调用;

2>在用户改变屏幕方向时,此方法会被调用;

3>在当前Activity跳转到其他Activity或者按Home键回到主屏,自身退居后台时,此方法会被调用。

第一种情况我们无法保证什么时候发生,系统根据资源紧张程度去调度;第二种是屏幕翻转方向时,系统先销毁当前的Activity,然后再重建一个新的,调用此方法时,我们可以保存一些临时数据;第三种情况系统调用此方法是为了保存当前窗口各个View组件的状态onSaveInstanceState的调用顺序是在onPause之前后(Android3.0之前是在onPause之前,之后是在onPause之后)。

(4)onRestoreInstanceState:

1>在Activity被覆盖或退居后台之后,系统资源不足将其杀死,然后用户又回到了此Activity,此方法会被调用;

2>在用户改变屏幕方向时,重建的过程中,此方法会被调用。我们可以重写此方法,以便可以恢复一些临时数据。
onRestoreInstanceState的调用顺序是在onStart之后。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值