1.2 Activity

         Activity是个应用组件,它给用户提供了为了完成某些工作而可以进行交互操作的界面,例如,电话详情,打电 话,发邮件,或是浏览地图。每一个Activity都有一个窗口来绘制自已的用户界面。通常来说,activity的窗口充满了整个屏幕,也可能比屏幕小并且浮动在其它窗口之上。

         应用程序通常是由一些松散的、但是相互绑定的Activity组成。一般来说,应用中的某个activity被指定为“主要”的activity,也就是当用户第一次运行应用时运行的activity。每一个activity都可以启动其它的activity来进行不同的动作。每次,当一个新的activity开始的时候,先前的activity就停止了,但是系统会把先前的activity保存在一个堆栈中(“后退堆栈”)。当一个新的activity开始时,它会被压入这个后退堆栈中并且获取用户焦点。后退堆栈遵循的是后进先出的原则。当用户在当前显示的堆栈中操作完成并按下了系统的返回键时,当前的activity就会从后退堆栈中弹出(被销毁),先前的activity就会得到恢复(更多详情请参见Tasks and Back Stack章节)。

         activity的停止是因为新的activity的开始,通过activity生命周期的回调方法来通知这种状态发生了变化。activity或 许会收到多个回调 - 不论系统创建、停止、恢复、销毁activity时 - 每个回调都给你提供了当状态发生变化时执行特定操作的机会。例如,当activity停止时,你需要释放一些占有较大内存的对象,例如网络连接或数据库连接。当activity恢复时,你可以重新获取一些必须的资源和恢复当activity停止时执行的操作。activity生命周期的所有内容就是这些状态的相互转换。

         该文档的剩余内容里讨论了如何创建和使用一个activity的基本知识,包括生命周期如何工作的完整的讨论。学完 本课后,你就可以正确的管理activity不同状态之间的转换了。

Creating an Activity - 创建Activity

         要创建一个activity,你必须得创建一个Activity的子类。当activity在生命周期的不同状态之间进行转换时,在你的 子类中,你需要实现一些回调方法以供应用调用,例如,当activity被创建、停止、恢复、或销毁时。下面是两个最重要的回调:

         onCreate():你必须实现这个方法。当创建activity时,系统会调用这个方法。在你的实现里,你应该初始化你的 activity的必须的组件。更重要的是,在方法里你必须调用setContentView()方法来定义你activity的用户界面所使用的布局。

         onPause():作为第一标识,系统会在用户离开你的activity时调用它(然而它经常不是意味着activity被销毁了)。通 常如果你需要保持当前会话的话,你所有的改动都应在这提交(因为用户可能不返回)。 

         为了在activity之间切换时给用户提供一个流畅的用户体验,你应该使用生命周期方法来处理意外的中断,意外的中断可能会导致activity被停止,甚至被销毁。所有的生命周期方法在管理activity生命周期(Managing the Activity Lifecycle)章节将会被讨论。

Implementing a user interface - 实现一个用户界面

         activity的用户界面由一系列有层次的视图提供。每个视图控制Activity窗口的特定矩形空间,以响应用户交互。例 如,一个视图可能是一个按钮,当用户触摸它时启动一个操作。

         Android提供了一些现成的视图,你可以使用它们来设计和组织布局。"Widgets"是在屏幕上提供了可视的(并且是交互式的)元素,例如:按钮、文本、复选框,或者图片。"Layouts"是从ViewGroup 里派生出来的,为它里面的子元素提供了唯一的布局模式,例如:linear布局,grid布局,relative布局。你也可以使用子类的View和ViewGroup(或者是已经存在的子类)来创建你自己的控件和布局,并把它们应用到你应用的布局里。

         使用视图定义布局最通用的办法是在应用资源里定义一个xml文件。一般来说,代码里定义了用户的行为,使用xml文件的方法,你可以保持用户界面的设计和用户的行为分离。你可以使用setContentView() 来设置你activity使用的布局,该方法需要传递布局文件的id。尽管如此,但是,你也可以在代码里创建新的视图,通过向 ViewGroup 里插入新的 View 来构建一个有层次的视图,最后把根ViewGroup 当作参数传递给setContentView()方法就可以了。

         你可以在 User Interface 文档里找到更多的关于创建用户界面的信息。

Declaring the activity in the mainfest - 在mainfest文件里申明activity

         为了使用activity,你必须在mainfest文件里申明你的activity。打开mainfest文件,在<application> 节点里申明子元素 <activity> ,这样就申明了一个activity。例如:

<manifest ... >

  <application ... >

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

      ...

  </application ... >

  ...

</manifest >

         在activity元素里,你可以申明一些其它的属性来定义一些东东,比如activity的标注,activity的图标,或者activity UI的样式等。 android:name 是唯一必须有的属性,它指定了activity所对应的类的名称。一旦你发布了你的应用,你就不应该改变这个名字了,如果你改变了这个名字,你可能会破坏一些功能,例如应用的快捷方式(相关博客 Things That Cannot Change )。

         在mainfest文件里申明activity的更多知识请参见 <activity> 章节。

Using intent fliters - 使用intent过滤器

         使用<intent-fliter>元素,可以为<activity> 元素指定不同的intent过滤器,申明过滤器的目的是为了指定使用哪些应用组件可以激活这个activity。

         当你使用Android SDK工具创建了一个新的应用程序时,工具为你自动生成的activity里就包含了一个intent过滤器,申明了该activity会响应"main"动作并且该动作应该被放置在"launch"分类里。代码如下:

<activity android:name=".ExampleActivity" android:icon="@drawable/app_icon">

    <intent-filter>

        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />

    </intent-filter>

</activity>

         <action> 元素说明了这是指向应用的"main"实体。<category> 元素指定了该activity应该在系统应用程序的启动列表里列出来(允许应用启动该activity)。

         如果你打算把你的应用做成私有的,不允许其它应用来激活你的activity,那么你不需要任何过滤器。就像上面的例子展示的那样,仅仅只应该有一个activity有"main"动作和"launch"分类。你想让其它应用使用的activity就不需要intent filters了,但是你自己可以使用显式的intent调用来启动它们(这会在后面的章节里讨论)。

         尽管如此,但是,如果你想让你的activity来响应由其它程序(或是你的程序)分发的隐式的intents,那么,你必须为你的activity定义额外的intent 过滤器。对于每一种你想响应的intent的类型,你必须在<activity> 标签里包含<intent-filter> 元素,<intent-filter> 标签里包含有 <action> 元素,你也可以添加<category> 元素或是<data>元素。这些元素指定了你的activity可以响应的intent的类型。

         在Intents and Intent Filters 章节,你可以学习到activity怎样去响应intents。

Starting an Activity - 启动activity

        可以通过调用startActivity()方法来打开另外一个activity,给该方法传递一个Intent参数来描述你要打开哪个activity。Intent参数既精确的指定了你要打开的activity,又可以描述你想要执行什么操作(android系统会根据你的描述为你选择合适的activity,甚至这个activity可能是不同应用里的)。Intent对象可以给要打开的activity里传递小量的数据。

      一般来说,经常会打开一个已知的activity。你可以使用类的名称来创建一个intent,显式的定义你要打开的activity。例如:

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

         尽管如此,但是,你还可以想在打开activity的同时,执行一些动作,例如:发送邮件,文本短信,或者状态更新,执行的这些动作所用到的数据就来自于你原来的activity。你想要执行这些操作,但是,你的应用里没有执行这些操作的activity,你可以使用设备上其它应用里的activity来完成这些操作。这个特性让intent变得非常有用--你只需要定义一个描述了执行哪种操作的intent,然后系统加载器会从其它应用里加载合适的activity来执行这些操作。如果系统里有多个可以处理你intent的activity,那么系统会弹出选择界面供用户选择。例如,如果你想要发送email邮件,你可以这样创建intent:

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

         传递给intent的参数EXTRA_EMAIL是代表着邮件接收方的emial地址的数组。当邮件应用响应该intent时,它把参数里的值获取到并把值放于邮件表单里的to(译者注:至)文本框里。在这种情况下,email应用的activity启动,当用户发送完邮件后,你应用的activity就恢复了。

Starting an activity for a result - 启动activity并且返回结果

     有时,你获取想让你启动的activity给原来的activity返回一个结果。你如果想这样做,那么调用startActivityForResult() 方法来启动activity。为了从打开的activity里接收到一个结果,需要在原来的activity里实现onActivityResult() 回调。当打开的activity完成时,它会给你的onActivityResult() 方法以intent的形式返回一个结果。

         例如,你可能想让用户从联系人列表里选择一个联系人,然后处理选择的联系人的信息。下面的代码展示了你如何创建itent,如何处理返回的结果:

private void pickContact() {
    // 创建选择联系人的intent,这是由内容提供者URI定义的、
    Intent intent = new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI);
    startActivityForResult(intent, PICK_CONTACT_REQUEST);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // 如果请求返回成功,并且请求代码是PICK_CONTACT_REQUEST
    if (resultCode == Activity.RESULT_OK && requestCode == PICK_CONTACT_REQUEST) {
        // 查询联系人的姓名
        Cursor cursor = getContentResolver().query(data.getData(),
        new String[] {Contacts.DISPLAY_NAME}, null, null, null);
        if (cursor.moveToFirst()) { // 如果查询不为空
            int columnIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME);
            String name = cursor.getString(columnIndex);
            // 用选择的联系人的姓名做一些东东...
        }
    }
}

         该示例展示了:为了处理activity返回的结果,使用onActivityResult()方法的基本逻辑。首先你得检查请求是否成功--如果请求成功,返回代码应该是RESULT_OK--还应该检查正在响应结果的请求是否是已知的--请求代码就对应着startActivityForResult()方法的第二个参数。通过由intent返回的数据(data参数)就可以处理activity返回的结果了。

             ContentResolver 执行了对content provider的查询,查询后返回一个游标,通过该游标可以读取查询到的数据。更多的信息,请查看Content Providers章节。

            使用intents的更多信息,请查看Intents and Intent Filters 章节。

Shutting  Down an Activity - 关闭Activity

        可以通过调用finish() 方法来关闭Activity。你也可以调用finishActivity() 关闭一个原来打开的单独的Activity。

        注意:大多数情况下,你不需要显示的使用方法来关闭activity。正如在下面android生命周期章节中描述的那样,Android系统会为你管理activity的生命周期,因此你不需要自己手动的关闭activity。调用这些方法可以会对用户体验产生不利的影响,如果你真的不想让用户回到某个activity时,你再去手动关闭activity吧。

Managing the Activity Lifecycle - 管理Activity的生命周期

         要创建一个健壮的、易用的应用,通过实现回调方法来管理你Activities的生命周期是非常重要的。activity的生命周期受到与它交互的activities、它的任务、回退堆栈的影响。

         从本质上来说,activity可以存在三种状态:

         Resumed:activity在屏幕的前台并获取了用户焦点。(该状态有时也被叫作"running")

         Paused:另外的activity在前台并获取了用户焦点,但是该activity仍然是可见的。也就是说,另外的activity在当前的activity之上,要么半透明显示,要么没有完全覆盖住屏幕。处理paused状态的activity完全是alive的(Activity 对象被保存在内存中,它保存了所有状态和成员变量,并且仍然绑定在window管理器上),但是系统处于内存极其低的状态时,它仍然可能会被干掉。

         Stopped:activity完全被另外的activity所遮盖(被遮盖的activity处于“后台”)。处于stopped状态的activity也是alive(Activity 对象被保存在内存中,它保存了所有状态和成员变量,但是没有绑定在window管理器上)。虽然如此,但是,对于用户来说,它不再可见,并且当其它地方需要内容时,系统会干掉它。

         如果activity处于paused或stopped状态,系统可以把它从内存中移除掉,要么询问用户是否需要关闭(调用activity的finish()  方法),要么直接干掉它的进程。当这个activity再次被打开时(在被关闭或是被干掉进程后),activity肯定得重新创建所有的东东。

Implementing the lifecycle callbacks - 实现生命周期的回调

        当一个activity在上述的不同状态之间转换时,是通过不同的回调方法对activity进行通知的。当activity的状态发生变化时,你可以重写所有的生命周期的回调方法来做一些适合的工作。下面的代码包含了生命周期的每个基本方法:

public class ExampleActivity extends Activity {

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        // activity被创建.

    }

    @Override

    protected void onStart() {

        super.onStart();

        // activity将要显示出来.

    }

    @Override

    protected void onResume() {

        super.onResume();

        // activity已经可见(当前activity是resumed状态).

    }

    @Override

    protected void onPause() {

        super.onPause();

        // 另外的activity获取焦点(当前activity将要变为"paused"状态).

    }

    @Override

    protected void onStop() {

        super.onStop();

        //activity 不再可见 (当前activity是stopped状态)

    }

    @Override

    protected void onDestroy() {

        super.onDestroy();

        // activity即将被销毁.

    }

}

         注意:正如上面的示例代码所示,生命周期方法的实现里,在写自己的代码之前,必须要调用父类的实现。

         这些生命周期的方法就定义了一个activity的整个生命。通过实现这些方法,你可以监听在activity生命周期里内嵌的三个循环:

  • activity的完整生命发生在调用 onCreate() 和调用 onDestroy() 之间。在onCreate()方法里,你的代码应该执行所有全局状 态的设置操作(例如定义布局等),并且在onDestroy() 方法里释放所有用到的资源。例如,你的activity如果在后台跑了一个线程在从网络上下载数据,那么,你就可以在onCreate()方法里创建并且在onDestroy()方法里停止后台的线程。
  • activity的可见生命发生在调用onStart() 和调用 onStop()方法之间。在这期间,用户可以在屏幕上看见activity并且能 与之发生交互。例如,当一个新的activity开始,原来的activity不再可见时,onStop()方法被调用。在这两个方法之间,你可以保存给用户展示activity时所需要的资源。例如,你可以在onStart() 方法里注册一个BroadcastReceiver来监听影响你UI的改变,并且当用户不需要看你展示的信息时,在onStop()方法里将其它取消掉。在activity的整个生命周期里,系统可以会多次调用onStart() 方法和 onStop()方法,因为对于用户来说,activity总是在可见与不可见之间来回切换着。
  • activity的前台生命发生在调用onResume() 方法和调用 onPause() 方法之间。在这期间,当前activity处于前台,获取了用户的焦点。一个activity可以很频繁的在前台与后台之间进行切换--例如,当设备休眠或者出现对话框时,onResume() 方法就被调用了。因为activity的状态可以经常转换,因此,为了避免引起用户等待的缓慢的状态转换的情况发生,请保持这两个方法拥有相当轻量级的代码。

        图1介绍了上面提示到循环,还说明了从一种状态转换到另外的状态可能经历的路径。矩形代表了当activity在不同状态之间进行转换时,你可以实现的回调方法,在这些回调里,你可以实现一些操作。

 

           图1 activity的生命周期

        表1里列出了同样的生命周期方法,更详细的描述了每一个生命周期的回调方法,并且在activity的整个生命周期里定位它们,包括在生命周期回调完成后,系统是否可以杀死activity。

        表1--activity生命周期回调方法的摘要

Method

Description

Killable   after?

Next

onCreate()

当activity首次被创建时调用。在这个方法里,你应该做你所有的静态设置--创建视图,给list绑定数据,等等。该方法有一个Bundle参数,它包含了activity先前的状态(如果它的状态被保存过,详情请参见随后的Saving Activity State)。

后面的方法是onStart()方法。

No

onStart()

    

onRestart()

当activity停止后,调用该方法,当activity再次重新启动之前调用它。

后面的方法是 onStart()方法。

No

onStart()

onStart()

当activity变得可见之前调用该方法。

如果当activity变为前台时,它后面的方法是 onResume() 方法, 如果当activity变为不可见时,它后面的方法是 onStop() 方法。

No

onResume() 

or

onStop()

    

onResume()

在activity开始和用户交互之前调用该方法。在这个点上,activity是处于activity堆栈的顶部的。

后面的方法是 onPause()方法。

No

onPause()

onPause()

当系统即将运行另外的activity时调用该方法。该方法的典型用法是用来提交未保存数据的,或是停止动画和其它可能消耗CPU的操作,等等。在这个方法里不论进行什么处理,都必须非常迅速,因为在这个方法之后,activity将不再是resumed状态,除非用户返回到该activity。

如果activity回到前台时,它后面的方法是 onResume() 方法,如果它变得不可见,它后面的方法是 onStop() 方法。

Yes

onResume() 

or

onStop()

onStop()

当activity不再可见时调用该方法。当activity被销毁时,会调用该方法,也有可能当另外的activity(要么是已经存在的,要么是新建的)变为resumed状态并将当前的activity覆盖时,也会调用该方法。

如果activity回到前台,它后面的方法是 onRestart() 方法,如果正在离开activity,它后面的方法是onDestroy()方法。

Yes

onRestart()

or

onDestroy()

onDestroy()

在activity被销毁之后调用该方法。这是activity接收到的最后的调用。要么因为activity结束了(有时是因为调用了finish()方法),要么是因为系统为了节省内存而将其销毁了。在这些状态之间,你可以使用isFinishing()方法进行判断。

Yes

nothing

         "Killable after?"这一列标识了在方法运行完成的任意时刻,不用执行activity其它的代码,系统就可以杀死activity所依附的进程。有三个方法被标识为yes(onPause()onStop(), 和 onDestroy() )。因为onPause()是这三个方法的第一次被执行的方法,所以一旦activity被创建,在某种紧急情况下,如果系统需要内存时,在activity所依附的进程被系统杀死之前,onPause()方法肯定是最后一个被调用的方法。因此,你应该在onPause()方法里保存重要的可持续性的数据(例如用户的编辑信息)。虽然如此,但是,在onPause()方法里保存的数据是有选择性的,因为在这个方法里的任何阻塞进程的程序都会阻止由当前activity到下一个activity的转换,并且降低用户体验性。

         在Killable列里被标识为No的方法在他们被调用的时候,会保护它们所依附的进程不会被杀死。因此,从onPause()状态到onResume()状态之间时,activity可能会被杀死。但是,直到onPause()再次被调用和返回前,activity处于不能被杀死状态。

         注意:activity,不是在表1里专门被定义为可杀死的,可能仍然会被系统干掉 -- 这会发生在系统没有资源可用的情况(极端情况)。activity可能被杀死的情况会在 Processes and Threading 章节做详细的讨论。

Saving activity state - 保存Activity的状态

         前面的内容(Managing the Activity Lifecycle)提到了,当activity处于paused或是stopped状态时,activity的状态会被保留的。这是事实,因为当activity处于paused或是stopped状态时,Activity对象会被保存在内存中--关于它的所有成员变量和状态都会被保存。因此,用户在activity里的任何改变都会被保存下来,所以,当activity返回到前台时(当它处于resumed状态时),所有的改变都在activity里。

         虽然如此,但是,当系统为了恢复内存而销毁一个activity时,内存中的activity对象也同时被销毁了,因此,系统不能仅仅只是使用activity的完整状态来进行恢复。而是当用户返回到已经销毁的activity时,系统会再次创建这个activity。可是,对于用户来说,它不知道系统已经销毁了他要看的activity并把它重建了,用户仍然会期望他看到的activity是他离开这个activity时的状态。在这种情况下,你要确保的是:activity相关的所有重要信息都要保存下来,可以通过实现一个回调方法来做到保存你activity的信息,该方法是:onSaveInstanceState()

         在activity容易被销毁之前,系统会调用onSaveInstanceState() 方法。系统会给该方法传递一个参数: Bundle ,在这个参数里,你可以使用诸如 putString() 和 putInt() 的方法来以键值对的形式来保存activity的信息。那么,如果系统杀死了你activity的进程,然后用户回到这个activity时,系统会重建这个activity并且给onCreate() 和 onRestoreInstanceState() 方法传递Bundle 参数。从这两个方法中的任一一个方法的Bundle 参数里,你都可以获取保存过的activity的状态。如果没有存储过状态信息,那么这两个方法的Bundle 参数是null(activity第一次被创建时就是这种情况)。

 

         图2:activity带着它的完整状态返回到前台接收用户焦点的两种途径:activity被销毁,然后重建,这种情况下必须存储过activity原先的状态;activity停止了,然后恢复,这种情况下activity的状态是完整的。

         注意:在activity被销毁之前调用onSaveInstanceState()  方法不是必要的,这是因为很多情况下是不需要保存状态的(例如当用户使用返回键离开activity时,这明显就是用户自己想关闭activity了)。如果系统调用了onSaveInstanceState() 方法,那它应该发生在onStop()方法之前或是onPause()方法之前。

         虽然如此,但是,即使你啥都没有做也没有实现onSaveInstanceState() 方法,某些activity的状态也会被Activity类的onSaveInstanceState() 方法的默认实现所存储。尤其是,默认的实现会为布局里的每个视图调用相应的onSaveInstanceState() 方法,这样的机制就允许每个视图为它自己提供应该要被存储的数据信息。几乎Android框架里的每个控件都酌情的实现了这个方法,因此当activity被重建时,UI里的任何可见的改变都会自动被保存和存储下来。例如,EditText  控件会自动保存用户输入的文本,CheckBox 控件会保存它是否被选中的状态。为了实现上述的这些,你唯一所需要做的就是给你想自动保存状态的每个控件一个唯一的ID标识(使用 android:id  属性)。如果控件没有ID,那么系统不会自动保存它的状态。

         尽管onSaveInstanceState() 方法的默认实现保存了activityUI的有用信息,但是你仍然需要重写它来保存其它的信息。例如,在activity的生命周期里,你可以需要存储改变过的成员变量的值(这些值可能和存储在UI里的值互有关系,但是存储整个UI的变量的值默认是不被保存的)。

         因为onSaveInstanceState()的默认实现保存了UI的状态,因此,如果你为了保存其它的值而要重写该方法,你应该在方法的最开始总是调用父类的方法。同样地,在onRestoreInstanceState() 方法里,如果你重写了它,在重写方法的最开始,你也应该总是调用父类的方法,这是因为默认的实现(译者注:即父类的方法)可以存储视图的状态。

         注意:因为onSaveInstanceState()方法不能保证肯定被调用,因此你应该使用它来保存一些activity瞬时的状态(UI的状态)--你坚决不要使用它来保存持久化的数据。在用户离开activity时,你应该在onPause() 方法里保存持久化的数据(例如应该保存到数据库里的数据)。

         一个测试应用保存状态能力的好办法是旋转设置使得屏幕方向发生变化。当屏幕方向发生变化时,系统为新的屏幕配置应用相应的资源时会把activity进行销毁并重建。仅就这一点而言,当activity被重新创建时,完全存储activity的状态是非常重要的,因为用户在使用应用时,会经常的改变屏幕的方向。

Handling configuration changes - 处理配置的改变

         在运行时,一些设备的配置可能会发生变化(例如屏幕方向,键盘的可用性,和语言等等)。当这样的改变发生时,Android会重新创建正在运行的程序(系统会调用activity的onDestroy() 方法,并且马上就调用onCreate() 方法)。通过自动加载应用中提供的可选择的资源(例如不同屏幕方向或尺寸下的不同布局)的行为来帮助应用适应新的配置。

         如上边描述的那样,如果你在屏幕方向发生变化时,合理设计了你的activity进行重启,那么你的应用在activity的生命周期里处理不期望的事件时,就非常有弹性了。

         在处理此类的重启时,最好的方法就是使用onSaveInstanceState() 和 onRestoreInstanceState() (或是onCreate() )方法来保存activity的状态,正如在前面讨论的那样做。

         关于在运行时发生的配置改变,和你如何处理它们的更多信息,请参见 Handling Runtime Changes 章节。

Coordinating activities -

         当在一个activity里启动另外一个时,这两个activity都经历了生命周期的变化。第一个activity暂停和停止了(如果它在后台仍然可见时,它不会停止的),而第二个activity被创建了。在这种情况下,如果这些activities在某些地方共享了数据,那么,理解第一个activity在第二个activity创建之前还没有完全停止就非常重要了。更准确的说,停止第一个activity的进程和创建第二个activity的进程是重叠的。

         生命周期回调的顺序被很好的定义了,尤其是当两个activity处理同一进程时,并且在一个activity里启动了另外的一个。下面就描述了activity A启动了activityB时,转变发生的顺序:

         1.  A的onPause() 方法执行。

         2.  B的onCreate()onStart(), and onResume()  方法顺序执行。(B现在获取用户焦点了)

         3.  然后,如果A在屏幕上不再可见,它的onStop() 方法被执行。

         生命周期回调的序列是可预见的,因此你可以管理从一个activity到另外一个activity时的变化的信息。例如,当第一个activity停止时,你必须把一些数据写入数据库,因为第二个activity需要用到它们。这时,你就只能在第一个activity的onPause() 方法里存储数据,而不是 onStop() 方法。

原文地址:https://www.cnblogs.com/wchhuangya/p/3260657.html