android应用开发(22)---Activity的生命周期

了解活动生命周期

当用户浏览,浏览并返回到您的应用程序时,应用程序中的 Activity实例将在其生命周期中的不同状态中转换。Activity类提供了一些回调允许活动知道一个状态已经改变的:该系统被创建,停止或恢复活性,或破坏该活动所在的过程。

在生命周期回调方法中,您可以声明用户离开并重新进入活动时活动的行为。例如,如果您正在构建流媒体视频播放器,则可能会暂停视频并在用户切换到其他应用时终止网络连接。当用户返回时,您可以重新连接到网络并允许用户从同一地点恢复视频。换句话说,每个回调允许您执行适合于给定状态更改的特定工作。在正确的时间做适当的工作并正确地处理转换,可以使您的应用更加健壮和高效。例如,生命周期回调的良好实现可以帮助确保您的应用程序避免:

  • 如果用户在使用应用程序时收到电话或切换到其他应用程序,则会崩溃。
  • 当用户没有使用它时消耗宝贵的系统资源。
  • 如果用户离开您的应用程序并在稍后返回,则会丢失用户的进度。
  • 当屏幕在横向和纵向之间旋转时,会损坏或丢失用户的进度。

本文档详细解释了活动生命周期。该文件从描述生命周期范式开始。接下来,它解释了每个回调:它们执行时在内部发生了什么,以及它们应该执行什么。然后简要介绍活动状态与进程被系统杀死的脆弱性之间的关系。最后,它讨论了与活动状态之间的转换有关的几个主题。

有关处理生命周期的信息(包括最佳实践指南),请参阅 使用生命周期感知组件处理生命周期以及保存UI状态要了解如何使用与架构组件结合的活动来构建强大的生产质量的应用程序,请参阅 应用程序架构指南。

活动生命周期概念

到的活性生命周期的阶段之间导航的过渡,活动类别提供一组核心六个回调: onCreate(), onStart()onResume(), onPause(), onStop(),和 onDestroy()当活动进入新状态时,系统调用每个回调。

图1展示了这种范例的视觉表现。

图1. 活动生命周期的简单说明。

当用户开始离开活动时,系统会调用方法来解除活动。在某些情况下,这种拆除只是部分; 该活动仍驻留在内存中(例如,当用户切换到另一个应用程序时),并且仍然可以回到前台。如果用户返回到该活动,则该活动从用户离开的地方恢复。系统杀死一个给定过程的可能性 - 以及其中的活动 - 取决于当时活动的状态。活动状态和记忆弹射提供了关于状态与弹射脆弱性之间关系的更多信息。

根据您的活动的复杂程度,您可能不需要实施所有生命周期方法。但是,重要的是要了解每个人并实施那些可确保您的应用按用户期望的方式行事的人。

本文档的下一部分详细介绍了用于处理状态之间转换的回调。

生命周期回调

本节提供有关在活动生命周期中使用的回调方法的概念和实现信息。

某些操作(如调用)属于活动生命周期方法本身。但是,实现相关组件操作的代码应该放置在组件本身中。为了实现这一点,您必须使依赖组件的生命周期感知。请参阅 使用生命周期感知组件处理生命周期以了解如何使您的从属组件生命周期感知。 setContentView()

onCreate()

您必须实现此回调,当系统首次创建活动时触发回调。在活动创建时,活动进入创建状态。在该onCreate() 方法中,您可以执行基本的应用程序启动逻辑,这些逻辑应该在活动的整个生命周期中只发生一次。例如,您的实现可能会将数据绑定到列表,将该活动与a关联 ,并实例化一些类作用域变量。此方法接收参数,该参数 包含活动先前保存状态对象。如果活动从未存在过,则该对象的值为空。 onCreate()ViewModelsavedInstanceStateBundleBundle

如果您有一个与生命周期相关的生命周期感知组件,它将收到该 ON_CREATE 事件。用@OnLifecycleEvent注解的方法将被调用,以便您的生命周期感知组件可以执行创建状态所需的任何设置代码。

下面的onCreate()方法示例 显示了该活动的基本设置,例如声明用户界面(在XML布局文件中定义),定义成员变量以及配置一些UI。在这个例子中,XML布局文件是通过传递文件的资源ID R.layout.main_activity来 指定的setContentView()

TextView mTextView;

// some transient state for the activity instance
String mGameState;

@Override
public void onCreate(Bundle savedInstanceState) {
   
// call the super class onCreate to complete the creation of activity like
   
// the view hierarchy
   
super.onCreate(savedInstanceState);

   
// recovering the instance state
   
if (savedInstanceState != null) {
        mGameState
= savedInstanceState.getString(GAME_STATE_KEY);
   
}

   
// set the user interface layout for this activity
   
// the layout file is defined in the project res/layout/main_activity.xml file
    setContentView
(R.layout.main_activity);

   
// initialize member TextView so we can manipulate it later
    mTextView
= (TextView) findViewById(R.id.text_view);
}

// This callback is called only when there is a saved instance that is previously saved by using
// onSaveInstanceState(). We restore some state in onCreate(), while we can optionally restore
// other state here, possibly usable after onStart() has completed.
// The savedInstanceState Bundle is same as the one used in onCreate().
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
    mTextView
.setText(savedInstanceState.getString(TEXT_VIEW_KEY));
}

// invoked when the activity may be temporarily destroyed, save the instance state here
@Override
public void onSaveInstanceState(Bundle outState) {
    outState
.putString(GAME_STATE_KEY, mGameState);
    outState
.putString(TEXT_VIEW_KEY, mTextView.getText());

   
// call superclass to save any view hierarchy
   
super.onSaveInstanceState(outState);
}

作为定义XML文件并传递给它的替代方法setContentView(),您可以View在您的活动代码中创建新对象,并通过将新的View插入到a中来 构建视图层次结构ViewGroup然后通过传递根ViewGroup来 使用该布局setContentView()有关创建用户界面的更多信息,请参阅 用户界面文档。

您的活动不处于创建状态。onCreate()方法完成执行后,活动进入启动 状态,系统将快速连续调用onStart() 和onResume()方法。下一节解释 onStart()回调。

onStart()

当活动进入开始状态时,系统调用此回调。onStart()调用使用户可以看到该活动,因为该应用程序准备进入前台并成为交互式活动。例如,此方法是应用程序初始化维护UI的代码的位置。

当活动移动到开始状态时,与活动生命周期关联的任何生命周期感知组件都将收到该 ON_START事件。

onStart()方法非常快速地完成,并且与创建状态一样,该活动不会保持驻留在已启动状态。一旦这个回调完成,活动进入 恢复状态,系统调用该 onResume()方法。

onResume()

当活动进入恢复状态时,它进入前台,然后系统调用onResume() 回调。这是应用程序与用户交互的状态。该应用停留在这种状态,直到发生某些事情将焦点从应用中移开。例如,这种事件可能是接到电话,用户导航到其他活动或设备屏幕关闭。

当活动转移到恢复状态时,与活动生命周期关联的任何生命周期感知组件都将收到该 ON_RESUME 事件。这是生命周期组件可以在组件可见并且处于前台时启用需要运行的任何功能的位置,例如启动相机预览。

当发生中断事件时,活动进入暂停 状态,系统调用 onPause()回调。

如果活动从暂停状态返回到恢复状态,则系统再次调用 onResume()方法。因此,您应该实现onResume() 初始化您在释放期间发布的组件 onPause(),并执行每次活动进入恢复状态时必须发生的任何其他初始化。

以下是组件接收ON_RESUME事件时访问摄像头的生命周期感知组件的示例 

public class CameraComponent implements LifecycleObserver {

   
...

   
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
   
public void initializeCamera() {
       
if (camera == null) {
            getCamera
();
       
}
   
}

   
...
}
上面的代码初始化相机一次 LifecycleObserver 接收ON_RESUME事件。但是,在多窗口模式下,即使处于暂停状态,您的活动也可以完全可见。例如,当用户处于多窗口模式并点击另一个不包含您的活动的窗口时,您的活动将移至暂停状态。如果您希望相机仅在应用程序恢复时处于活动状态(在前景中可见并处于活动状态),请在上面显示的ON_RESUME事件之后初始化相机。如果您希望在活动暂停但可见的情况下保持摄像机处于活动状态(例如,在多窗口模式下),则应该在ON_START事件之后初始化摄像机。但请注意,如果在您的活动暂停时让相机处于活动状态,则可能会拒绝在多窗口模式下将相机访问到另一个恢复的应用程序。有时可能需要在您的活动暂停时保持相机处于活动状态,但如果您这样做,则实际上可能会降低整体用户体验。仔细考虑在生命周期的哪个地方更适合在多窗口环境中控制共享系统资源。要了解更多关于支持多窗口模式的信息,请参阅多窗口支持

无论您选择在哪个构建事件中执行初始化操作,请确保使用相应的生命周期事件释放资源。如果您在ON_START事件之后初始化某些内容,请在ON_STOP事件之后释放或终止它。如果您在ON_RESUME事件之后进行初始化,请在ON_PAUSE事件之后释放。

请注意,上面的代码片段将摄像机初始化代码放置在生命周期感知组件中。您可以直接将此代码放入活动生命周期回调中,例如 onStart(), onStop()但不建议这样做。将此逻辑添加到独立的支持生命周期的组件中,可让您跨多个活动重用组件,而无需复制代码。请参阅 使用生命周期感知组件处理生命周期 以了解如何创建生命周期感知组件。

onPause()

系统调用此方法作为用户离开活动的第一个指示(尽管它并不总意味着活动正在被销毁); 它表明该活动不再处于前台(尽管如果用户处于多窗口模式,它仍然可见)。onPause()Activity处于暂停状态时,使用该方法暂停或调整不应该继续(或者应该继续适度)的操作,并且您希望很快恢复。活动可能会进入此状态有几个原因。例如:

  • 正如onResume()部分所述,某些事件会中断应用程序的执行这是最常见的情况。
  • 在Android 7.0(API等级24)或更高版本中,多个应用程序以多窗口模式运行。因为任何时候只有其中一个应用程序(窗口)有焦点,系统会暂停所有其他应用程序。
  • 一个新的,半透明的活动(如对话框)打开。只要该活动仍然部分可见但不重点,它仍然处于暂停状态。

当活动转到暂停状态时,与活动生命周期关联的任何生命周期感知组件都将收到该 ON_PAUSE事件。这是生命周期组件可以停止在组件不在前台运行时不需要运行的任何功能的地方,例如停止相机预览。

您也可以使用此 onPause()方法释放系统资源,传感器的手柄(如GPS),或在活动暂停并且用户不需要它们时可能影响电池寿命的任何资源。但是,如上面在onResume()部分中所述,如果在多窗口模式下,暂停的活动仍可以完全可见。因此,您应该考虑使用onStop()而不是onPause()来完全释放或调整与UI相关的资源和操作,以更好地支持多窗口模式。

以下LifecycleObserver 响应ON_PAUSE事件的示例是上述ON_RESUME事件示例的对应部分,释放在收到ON_RESUME事件后初始化的摄像头:

public class JavaCameraComponent implements LifecycleObserver {

   
...

   
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
   
public void releaseCamera() {
       
if (camera != null) {
            camera
.release();
            camera
= null;
       
}
   
}

   
...
}

请注意,在LifecycleObserver接收到ON_PAUSE事件后,上面的代码片段会放置相机发布代码。如前所述,请参阅 使用生命周期感知组件处理生命周期 以了解如何创建生命周期感知组件。

onPause()执行非常简短,并且不一定有足够的时间执行保存操作。出于这个原因,你应该使用 onPause()保存应用程序或用户数据,进行网络通话,或执行数据库事务; 在方法完成之前,这样的工作可能无法完成。相反,您应该在执行重负载关闭操作期间 onStop()有关在执行期间执行的合适操作的更多信息 onStop(),请参阅 onStop()有关保存数据的更多信息,请参阅 保存和恢复活动状态

onPause()方法的完成并不意味着活动离开暂停状态。而是,活动保持这种状态,直到活动恢复或对用户完全不可见为止。如果活动恢复,系统再次调用onResume()回调。如果活动从暂停状态返回到恢复状态,则系统将Activity实例驻留在内存中,并在系统调用时调用该实例 onResume()在这种情况下,您不需要重新初始化任何导致恢复状态的回调方法中创建的组件。如果活动完全不可见,则系统调用 onStop()下一节讨论onStop()回调。

onStop()

当您的活动对用户不再可见时,它已进入 停止状态,并且系统调用 onStop()回调。例如,当新推出的活动覆盖整个屏幕时,可能会发生这种情况。系统也可能onStop() 在活动完成并即将终止时调用

当活动进入停止状态时,与活动生命周期关联的任何生命周期感知组件都将收到该 ON_STOP事件。这是生命周期组件可以停止在组件在屏幕上不可见时不需要运行的任何功能的地方。

在该onStop()方法中,应用程序应释放或调整应用程序对用户不可见时不需要的资源。例如,您的应用可能会暂停动画或从细粒度切换到粗粒度位置更新。 即使用户在多窗口模式下查看您的活动,使用 onStop()而不是onPause()确保与用户界面相关的工作仍在继续。

您还应该使用onStop() 执行相对CPU密集型关机操作。例如,如果您找不到更合适的时间将信息保存到数据库,那么您可能会在此期间这样做onStop()以下示例显示了其中的一个实现 onStop()将草稿备注的内容保存到持久性存储:

@Override
protected void onStop() {
   
// call the superclass method first
   
super.onStop();

   
// save the note's current draft, because the activity is stopping
   
// and we want to be sure the current note progress isn't lost.
   
ContentValues values = new ContentValues();
    values
.put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText());
    values
.put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle());

   
// do this update in background on an AsyncQueryHandler or equivalent
    mAsyncQueryHandler
.startUpdate (
            mToken
,  // int token to correlate calls
           
null,    // cookie, not used here
            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.
   
);
}

请注意,上面的代码示例直接使用SQLite。你应该使用Room,一个持久性库,它提供了一个SQLite抽象层。要详细了解使用Room的好处以及如何在应用中实现Room,请参阅 Room Persistence Library 指南。

当您的活动进入停止状态时,该Activity 对象将保持驻留在内存中:它维护所有状态和成员信息,但未附加到窗口管理器。当活动恢复时,活动将回收此信息。您不需要重新初始化任何导致恢复状态的回调方法期间创建的组件。系统还会跟踪View布局中每个对象的当前状态,因此如果用户将文本输入到EditText小部件中,则会保留该内容,因此您无需保存和恢复它。

注意:一旦您的活动停止,如果系统需要恢复内存,系统可能会销毁包含该活动的进程。即使系统在活动停止时销毁进程,系统仍然会将View 对象的状态(如EditText小部件中的文本保留在 Bundle(一组键值对中),并在用户返回时恢复它们活动。有关恢复用户返回的活动的更多信息,请参阅 保存和恢复活动状态

从停止状态,活动要么回到与用户交互,要么活动完成运行并消失。如果活动回来,系统会调用onRestart()如果Activity完成运行,则系统调用 onDestroy()下一节解释onDestroy() 回调。

onDestroy()

onDestroy()在活动被破坏之前调用。系统调用此回调,因为:

  1. 活动正在完成(由于用户完全放弃活动或由于 finish()被称为活动),或者
  2. 系统会暂时破坏由于配置更改(如设备旋转或多窗口模式)导致的活动,

当活动进入停止状态时,与活动生命周期关联的任何生命周期感知组件都将收到该 ON_DESTROY事件。这是生命周期组件在销毁活动之前可以清理所需的任何内容的位置。

与其将逻辑放入您的活动中以确定其销毁原因,您应该使用ViewModel对象来包含活动的相关视图数据。如果活动将因配置更改而重新创建,则ViewModel无需执行任何操作,因为它将被保留并提供给下一个Activity实例。如果Activity不会被重新创建,那么ViewModel将会onCleared()调用这个 方法,它可以在被销毁之前清理它需要的所有数据。

您可以使用该isFinishing()方法区分这两种情况 

如果活动正在结束,则onDestroy()是活动接收的最终生命周期回调。如果onDestroy()作为配置更改的结果被调用,系统会立即创建一个新的活动实例,然后 在新配置中调用 该新实例。 onCreate()

onDestroy() 回调应释放还没有被释放由以前的回调,如所有资源onStop()

活动状态和从记忆中弹出

系统在需要释放RAM时会终止进程; 系统杀死给定进程的可能性取决于当时进程的状态。进程状态又取决于进程中运行的活动的状态。表1显示了进程状态,活动状态和系统杀死进程的可能性之间的相关性。

被杀的可能性过程状态活动状态
最小前景(有或将要获得重点)创建已
启动
恢复
更多背景(失去焦点)已暂停
背景(不可见)停止
摧毁

表1.流程生命周期与活动状态之间的关系

系统不会直接杀死一个活动来释放内存。相反,它会杀死活动运行的过程,不仅会摧毁活动,还会摧毁流程中运行的所有其他活动。要了解在发生系统启动的进程死亡时如何保留和恢复活动的UI状态,请参阅保存和恢复活动状态

用户也可以通过使用“设置”下的“应用程序管理器”来终止相应应用程序来终止进程。

有关一般进程的更多信息,请参阅 进程和线程有关流程生命周期如何与其中的活动状态关联的更多信息,请参阅该页面的 流程生命周期部分。

保存和恢复瞬态UI状态

用户期望活动的UI状态在整个配置更改期间保持不变,例如旋转或切换到多窗口模式。但是,当这种配置更改发生时,系统会默认销毁活动,并删除存储在活动实例中的任何UI状态。同样,如果用户暂时将应用程序从应用程序切换到其他应用程序,然后再回到应用程序,用户希望UI状态保持不变。但是,当用户离开并且您的活动停止时,系统可能会破坏您的应用程序的进程。

当活动被破坏,由于系统的限制,你应该使用的组合保存用户的瞬时UI状态 ViewModel, 和/或本地存储。要了解有关用户期望与系统行为的更多信息,以及如何最好地保留跨系统启动的活动和进程死亡的复杂UI状态数据,请参阅 保存UI状态。 onSaveInstanceState()

本节概述什么是实例状态,以及如何实现onSaveInstance()方法,这是对活动本身的回调。如果您的UI数据是简单轻量的,比如原始数据类型或简单对象(如String),那么您可以单独使用onSaveInstanceState()来跨越配置更改和系统启动的进程终止来保持UI状态。不过,在大多数情况下,您应该使用ViewModel和onSaveInstanceState()(如 保存UI状态所述),因为onSaveInstanceState()会导致序列化/反序列化成本。

实例状态

有几种情况会导致您的活动由于正常的应用程序行为而遭到破坏,例如用户按下“后退”按钮或者您的活动通过调用finish() 方法表示其自身销毁 当您的活动因用户按下“后退”或活动自行完成而被销毁时,系统和用户对该Activity实例的概念都将永远消失。在这些情况下,用户的期望与系统的行为相匹配,并且您没有任何额外的工作要做。

但是,如果系统由于系统限制(例如配置更改或内存压力)而破坏活动,则尽管实际 Activity 实例不存在,但系统还是会记住它存在。如果用户尝试导航回活动,系统将使用一组保存的数据创建该活动的新实例,该数据描述活动在销毁时的状态。

系统用于恢复先前状态的已保存数据称为实例状态,是存储在Bundle对象中的键值对的集合默认情况下,系统使用Bundle实例状态来保存有关View活动布局中每个对象的信息(例如输入到EditText窗口小部件中的文本值 )。因此,如果您的活动实例被销毁并重新创建,那么布局的状态将恢复到之前的状态,并且不需要您的代码。但是,您的活动可能包含更多想要恢复的状态信息,例如跟踪用户活动进度的成员变量。

注意:为了使Android系统恢复活动中视图的状态,每个视图必须具有由android:id属性提供的唯一ID 

一个Bundle对象不适合保存多余数量的数据,因为它需要在主线程上进行序列化并消耗系统进程内存。要保留超过极少量的数据,您应该采用综合方法来保存数据,使用持久本地存储, onSaveInstanceState() 方法和 类,如 保存UI状态所述。 ViewModel

使用onSaveInstanceState()保存简单轻量级的UI状态

当您的活动开始停止时,系统会调用该 onSaveInstanceState() 方法,以便您的活动可以将状态信息保存到实例状态包中。此方法的默认实现可以保存有关活动视图层次结构状态的瞬态信息,例如EditText小部件中的文本或小部件的滚动位置 ListView

为了保存活动的其他实例状态信息,必须覆盖 onSaveInstanceState() 并添加键值对,以便Bundle在事件意外销毁时保存对象。如果您重写onSaveInstanceState(),则如果您希望默认实现保存视图层次结构的状态,则必须调用超类实现。例如:

static final String STATE_SCORE = "playerScore";
static final String STATE_LEVEL = "playerLevel";
// ...


@Override
public void onSaveInstanceState(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()finish()

要保存持久性数据(例如用户首选项或数据库数据),当您的活动处于前台时,应该采取适当的机会。如果没有这样的机会出现,您应该在该onStop()方法期间保存这些数据 

使用保存的实例状态恢复活动UI状态

当您的活动在之前被销毁之后重新创建时,您可以从Bundle系统传递到您的活动中恢复已保存的实例状态无论是onCreate()和 回调方法收到同样的 包含实例状态信息。 onRestoreInstanceState()Bundle

由于 调用方法是否系统正在创建活动的新实例或重新创建前一个实例,因此必须在尝试读取状态之前检查状态Bundle是否为空。如果它为空,那么系统正在创建一个活动的新实例,而不是恢复之前被销毁的实例。 onCreate()

例如,下面的代码片段显示了如何恢复一些状态数据: onCreate()

@Override
protected void onCreate(Bundle savedInstanceState) {
   
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 saved state
        mCurrentScore
= savedInstanceState.getInt(STATE_SCORE);
        mCurrentLevel
= savedInstanceState.getInt(STATE_LEVEL);
   
} else {
       
// Probably initialize members with default values for a new instance
   
}
   
// ...
}

您可以选择执行 ,而不是在系统调用方法之后 恢复状态 系统 仅在存在保存状态才能恢复的情况下调用 ,因此不需要检查是否为空: onCreate() onRestoreInstanceState()onStart() onRestoreInstanceState()Bundle

public void onRestoreInstanceState(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);
}

警告:始终调用超类实现, 以便默认实现可以恢复视图层次结构的状态。 onRestoreInstanceState()

在活动之间进行导航

应用程序可能会在应用程序的整个生命周期中进入或退出一个活动,可能很多次。例如,用户可以点击设备的后退按钮,或者该活动可能需要启动不同的活动。本部分介绍实施成功活动转换时需要了解的主题。这些主题包括从其他活动开始活动,保存活动状态以及恢复活动状态。

从另一个开始一个活动

一个活动通常需要在某个时候开始另一项活动。例如,当应用程序需要从当前屏幕移动到新屏幕时,就会出现这种需求。

取决于您的活动是否想要从新活动返回的结果即将开始,您可以使用startActivity() 或startActivityForResult() 方法开始新活动 无论哪种情况,您都会传入一个Intent对象。

Intent对象指定要开始的确切活动或描述您要执行的操作的类型(并且系统会为您选择适当的活动,甚至可能来自不同的应用程序)。一个Intent对象还可以携带少量的数据供启动的活动使用。有关Intent该类的更多信息,请参阅Intents和Intent Filters

startActivity()

如果新开始的活动不需要返回结果,则当前活动可以通过调用该startActivity() 方法来启动它 

在您的应用程序中工作时,您通常需要简单地启动已知的活动。例如,以下代码片段显示了如何启动一个名为的活动SignInActivity


Intent intent = new Intent(this, SignInActivity.class);
startActivity
(intent);

您的应用程序可能还希望使用您的活动中的数据执行某些操作,例如发送电子邮件,短信或状态更新。在这种情况下,您的应用程序可能没有自己的活动来执行此类操作,因此您可以利用设备上的其他应用程序提供的活动,它们可以为您执行操作。这就是意图真正有价值的地方:您可以创建一个描述您想要执行的操作的意图,并且系统从另一个应用程序启动相应的活动。如果有多个活动可以处理意图,那么用户可以选择使用哪一个。例如,如果您想允许用户发送电子邮件,则可以创建以下意向:

Intent intent = new Intent(Intent.ACTION_SEND);
intent
.putExtra(Intent.EXTRA_EMAIL, recipientArray);
startActivity
(intent);

EXTRA_EMAIL加入额外的意图是该电子邮件应该发送电子邮件地址的字符串数组。当一个电子邮件应用程序响应这个意图时,它读取额外提供的字符串数组,并将它们放在电子邮件组合表单的“to”字段中。在这种情况下,电子邮件应用程序的活动开始,当用户完成时,活动恢复。

startActivityForResult()

有时您想在活动结束时从活动中取回结果。例如,您可以开始一项活动,让用户在联系人列表中选择一个人; 当它结束时,它返回被选中的人。为此,您可以调用 startActivityForResult(Intent, int) 方法,其中integer参数标识调用。此标识符旨在消除startActivityForResult(Intent, int) 来自同一活动的多个呼叫之间的歧义 它不是全局标识符,不会与其他应用程序或活动发生冲突。结果通过您的onActivityResult(int, int, Intent) 方法返回 

当一个孩子活动退出时,它可以调用setResult(int)将数据返回给其父代。儿童活动必须始终提供结果代码(可以是标准结果 RESULT_CANCELEDRESULT_OK,或者提供任何自定义值开始RESULT_FIRST_USER另外,子活动可以选择返回一个Intent 包含它想要的其他数据对象。父活动使用该 onActivityResult(int, int, Intent) 方法以及最初提供的父活动的整数标识符来接收信息。

如果某个子活动由于某种原因(例如崩溃)而失败,那么父活动就会收到包含该代码的结果RESULT_CANCELED

public class MyActivity extends Activity {
     
// ...

     
static final int PICK_CONTACT_REQUEST = 0;

     
public boolean onKeyDown(int keyCode, KeyEvent event) {
         
if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
             
// When the user center presses, let them pick a contact.
             startActivityForResult
(
                 
new Intent(Intent.ACTION_PICK,
                 
new Uri("content://contacts")),
                 PICK_CONTACT_REQUEST
);
           
return true;
         
}
         
return false;
     
}

     
protected void onActivityResult(int requestCode, int resultCode,
             
Intent data) {
         
if (requestCode == PICK_CONTACT_REQUEST) {
             
if (resultCode == RESULT_OK) {
                 
// A contact was picked.  Here we will just display it
                 
// to the user.
                 startActivity
(new Intent(Intent.ACTION_VIEW, data));
             
}
         
}
     
}
 
}

协调活动

当一项活动开始另一项活动时,它们都会经历生命周期转换。第一个活动停止操作并进入暂停或停止状态,而另一个活动则被创建。如果这些活动共享保存在光盘或其他地方的数据,重要的是要明白,第一个活动在创建第二个活动之前尚未完全停止。相反,启动第二个过程的过程与停止第一个过程的过程重叠。

生命周期回调的顺序已被很好地定义,特别是当两个活动处于同一个进程(应用程序)并且一个正在启动另一个时。以下是活动A启动活动B时发生的操作顺序:

  1. 活动A的onPause()方法执行。
  2. 活动B的onCreate(), onStart()和 onResume()方法按顺序执行。(活动B现在有用户焦点。)
  3. 然后,如果活动A在屏幕上不再可见,则onStop()执行方法。

这种可预测的生命周期回调序列允许您管理从一个活动到另一个活动的信息转换

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值