Task和Back Stack(一)

来源:互联网 发布:曾经最火的网络歌曲 编辑:程序博客网 时间:2024/06/10 16:36

        首先说一下我遇到过的问题,在我的应用中有两个Activity,A和B,其中B是dialog的形式。我需要从A传递数据到B中,在B中完成操作并将结果回传给A。一般情况下,由于Activity的默认启动模式是standard,那么这个操作直接在A中重写onActivityResult(int requestCode, int resultCode, Intent data), 然后通过startActivityForResult(intent, requestCode);跳转,最后在B中通过setResult(resultCode, intent), 并finish()回传就可以了。可是,当我快速点击两次跳转按钮时,居然连续出现了两个B(B1-B2)叠加在一起,这时点击Back按键回退,会先回退到第一个出现的B1,再回退才回到A。第一感觉是启动模式模式的问题,所以在一知半解的情况下把B的启动模式改成了singleTask,再试一次,果然快速多次点击也只能出现一个了。但是新的问题又出现了,从B中回传数据的时候,死活传不过来,也不报错。再改成singleTop试一次,数据可以回传了,可是快速点击,偶尔还是会连续出现两个Activity B,等于又回到了问题的原点。按理说Activity B使用singleTop模式好像是不应该连续出现两个B的吧??????于是,来文档中寻找答案。

        之所以翻译文档,主要是出于对英语的爱好。中英文的语言习惯还是有一定的区别,只是希望在条件允许的情况下,能够有更适合自己理解和学习也更符合中文语言习惯的一个版本。


        前言
        一个应用通常包含多个activity, 每个activity根据用户能够进行的特定操作而设计,同时,允许通过一个activity启动其他的activity。比如,一个发送邮件的应用可以包含一个activity用来展示新邮件列表,当用户选择一份邮件时,打开另外一个activity用来查看邮件的内容。
        一个activity甚至能够打开同一设备上其他应用中的activity。比如,当你的应用想要发送一份Email,你可以定义一个Intent用来进行这个发送的动作,并携带一些数据,如邮件地址和内容等信息。此时,来自另外一个应用中申明能够处理该Intent的activity将会打开。这种情况下,该intent的出发点是发送邮件,所以一个邮件应用的组成activity会被启动(如果存在多个activity支持同一个Intent,则系统会让用户选择使用哪个),当邮件发送完成后,你自己应用的activity将被恢复,这样邮件应用就像是你自己应用的一部分。虽然这些activity可能来自不同的应用,但android系统会将两个activity保持在同一个Task中以维护用户的操作喜好。

        什么是Task和Back Stack
        Task就是一个activity的集合,Task中保存的是用户在进行一项工作的时候需要与之进行交互的一组activity。这些activity根据他们被开启的顺序被排列在栈中,既所谓的“Back Stack”。
        通常情况下,设备的Home页是启动这些Task的地方。当用户通过点击设备主页的应用图标或通过快捷键启动一个应用时,该应用的Task来到前台。如果该应用当前没有启动对应的Task,则系统会新建一个Task,并把应用的启动Activity或这说主Activity开启,同时将该Activity作为对应back stack的根activity。
        当通过当前的activity启动另外一个activity时,新生成的activity被压入到back stack的栈顶,并获取当前焦点。之前的activity会停止,并被保持在栈中。当一个activity停止的时候,系统会保持其当前(既停止时)交互的状态。当用户点击Back按键回退时,当前activity会从应用的栈顶弹出,并被销毁,而前一个activity则会被恢复resume,这个activity停止时的状态也会被恢复。activity在back stack中是不可重排的,只会被压入栈中或从栈中弹出,当一个activity被当前activity启动时,当前activity会被压入栈中,用户使用Back按键回退时,该activity会从back stack中弹出。如此看来,back stack可以被理解成一个“先进后出”的对象结构。表Figure 1以时间线的形式,展示了不同时刻activity之间进行转换的过程,使这个转化过程更加形象化。



        如果用户继续点击回退,那么每个activity都会从栈中弹出,以显示在它之前的一个activity, 直到用户回到设备的主页面(或者在此应用的Task开始之前正在运行的activity),当所有的activity都被清楚出栈的后,该Task也随之销毁。
        一个Task是一个紧密结合的单元,当用户开启另外一个Task或者通过Home按键回到设备主页的时候,该Task会移动到后台。当Task移动到后台时,这个Task内的所有的activity也随之停止,但该Task的back stack仍然保持完整性,只不过,当其他的Task占据前台位置的时候,该Task暂时失去了焦点,如下Figure 2所示。这个Task可以回到前台,用户也可以从其停止的地方开始,继续进行操作。举例说明,假设当前Task(Task A)的back stack持有三个activity,有两个activity在当前activity的底部。当用户点击Home按键回到主页,然后通过一个应用的入口启动一个新的应用。那么当主页出现的时候,Task A会移动到后台运行,新的应用启动的时候,系统为该应用启动一个新的Task(Task B),并生成对应的back stack。当用户与新启动的应用进行交互操作之后,点击Home按键回到设备主页面,再选择之前启动的应用,既Task A。此时Task A回到前台,Task A中的三个activity都是完好无损的,并且该Task对应back stack中的栈顶activity将会恢复resume。这个时候,用户同样能够通过返回主页并选择另一个应用,而回退到Task B(或者从最近使用的apps面板中选择该应用的Task)。这是android系统中多任务的一个实例。



注意:同一时刻,可以有多个任务被放置到后台,只不过,用户同时在后台运行多个Task时,系统可能会为了恢复内存而销毁activity,从而导致activity的状态丢失,下面小节详解activity的状态。



0 0
原创粉丝点击