欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

理解任务和返回栈

程序员文章站 2022-05-28 12:51:22
当执行一个确定的工作的时候,一个任务是和用户交互的activity的集合。这些activity被排列在栈中(返回栈),每一个activity是被打开的。例如,一个email app有一个activity去显示消息列表,当点击一个新的消息时打开一个新的activity,新的activity被加入到返回 ......

 

   当执行一个确定的工作的时候,一个任务是和用户交互的activity的集合。这些activity被排列在栈中(返回栈),每一个activity是被打开的。例如,一个email app有一个activity去显示消息列表,当点击一个新的消息时打开一个新的activity,新的activity被加入到返回栈中。如果用户按下返回键,新的activity会从栈中弹出。

   当app运行在多窗口环境中,系统为每一个窗口单独管理任务,每一个窗口可能有多个任务,系统基于每一个窗口来管理任务或任务组。

   设备主屏幕是大多数任务的起始地方,当用户触摸app启动程序中的图标(主屏幕上的快捷方式),app的任务会出现在前台。如果app的任务不存在(app没有被使用过),然后一个新的任务会被创造并且main activity打开作为栈的根activity。

   当 当前activity打开一个新的activity,新的activity会被压入栈的顶部并获取焦点。前一个activity 保留在栈中,但是被stop。当一个activity被stop,系统保留用户接口的当前状态。当用户按下back键,当前activity被弹出栈顶(activity被毁灭),并且前一个activity被恢复(前一个activity的UI状态被恢复)。在栈中的activity从来不被从新排列,只能被压入或者弹出栈。

下图展示了进栈和出栈

 理解任务和返回栈

 

 

   如果用户继续按下back键,在栈中的activity被弹出并显示前一个activity,直到用户返回到HOME屏幕。当所有的activity从栈中移除,任务不再存在。

 理解任务和返回栈

 

   一个任务是一个有凝聚力的单元,当一个新的任务打开时,或者按下home键返回到主屏幕,任务被移到后台。任务在后台运行,所有的activity是stop状态,这个任务的返回栈是完好的,这个任务只是丢失掉聚焦点被另一个任务取代。在图片2中,当前的任务A有三个activity在栈中,两个在当前activity之下。当用户按下home键,从主界面开启一个新的app。当home屏幕显示的时候,任务A进入后台。当新的app启动,系统启动一个新的任务为app使用他自己的activity栈。在和app交互之后,用户返回home屏幕并且选择app打开任务A。现在,任务A返回到前台,在栈中的三个activity是完好无损的,在栈顶的activity被恢复。同样,也可以这样返回到任务B。

   注意:可以同时在后台执行多个任务。但是,如果用户同时运行多个后台任务,系统可能会开始销毁后台活动以恢复内存,从而导致活动状态丢失

 

   因为在返回栈中的activity是从来不被再次排列的,如果app允许用户去开启一个单独的activity从多个activity中,一个新的activity实例被创建并且被放在栈顶(而不是将任何以前的活动实例带到顶部)。因此,在app中的一个activity可能被创建多次(也可能从不同的任务中)。在图片3中展示了这种情况。

总结activity和任务的默认表现:

       当activity A开启activity B,activity A是stop状态,但系统会保留他的状态。如果用户按下back键在activity B,activity A恢复保留的状态。

       当用户按下home键离开一个任务,当前activity进入stop状态并且他的任务进入后台。系统保留在栈中的每一个activity的状态。如果用户之后恢复这个任务通过选择快捷图标开启这个任务,这个任务处于前台并且恢复在栈顶的activity的状态。

        如果用户按下back键,当前activity从栈中弹出并且毁灭。在栈中的前一个activity被恢复。当activity被毁灭,系统不会保留这个activity的状态。

        activities可能被实例化多次,甚至从另一些任务中。

   

导航设计:

   关于app导航如何工作在安卓中,阅读

 

管理任务

   安卓管理任务和返回栈正如上述所说-把所有activity按照顺序放入同一个任务和后进先出的栈-大多数工作都工作的十分好,你不必关心你的activity如何和task和返回栈交互。但是,你可能想要停止默认行为。大概你想要在你的app中的一个activity启动一个新的任务,当activitiy是被start的时候。或者当你启动activity的时候,你想要打开一个现存的实例(而不是创造一个新的实例在返回栈的栈顶)。或者当用户离开任务的时候,你只想要在返回栈中保留根activity。

   你可以使用manifest中的<activity>中的属性和在intent中的flags传递到startActivity()中,去实现这些事情。

   <activity>中的可用属性:

  •    
  •    
  •    
  •    
  •    
  •    

   intent中的flag:

  •    
  •    
  •    

 

   在下面的部分,将会介绍如何使用这些属性和flag,定义如何和任务和返回栈交互

 

   单独讨论activity在最近屏幕是如何描述和管理的,可以看

   一般不要修改默认行为,如果要修改,请做充分的测试确保可用性。

 

默认启动模式:

   启动模式允许你定义一个activity的实例如何和当前任务联系交互。你可以使用两种方式定义不同的启动模式。

l  利用mainfest文件

当在manifest文件中声明一个activity,你可以指定activity如何和task交互。

l  利用intent的flag

当你调用startActivity()时,你可以include一个flag在intent中。

   例如,如果activity A启动activity B,B可以在manifest中定义如何和当前task进行交互,activity A也可以请求activity B应该如何和当前任务交互。如果两个activity都定义了activity B如何和任务交互,然后activity A的请求(在inent中定义的)比activity B的请求(在manifest中定义)更优先。

 

利用manifest文件

   当声明一个activity在manifest文件,你可以指定activity如何利用这些元素和任务交互。

   launchMode属性指定了一个指令,activity如何被启动到任务中。

  

   Standard(默认模式):

      默认。系统在任务中创建一个新的activity实例,activity可以被实例化多次,每一个实例可能属于不同的任务,并且一个任务可能有多个实例。

   SingleTop:如果activity在顶部,再次被调用不会被创建,其它情况创建一个新实例

      如果activity的实例早已存在在当前任务的顶部,系统会通过调用他的onNewIntent()方法找到这个实例,而不是创造一个新的实例。Activity可以被实例化多次,每一个实例可能属于不同的任务,一个任务可能有多个实例(仅限于在栈顶的activity不是现存的activity,下面解释)

      例如,假设一个任务返回栈由activity A,B,C,D组成,D在栈顶。一个intent寻找activity D。如果D使用默认standard启动模式,一个新的实例被启动,栈就变成了A-B-C-D-D。然而如果是singleTop模式,现存的D的实例接收intent通过onNewIntent(),因为D实例在栈顶,所以不会被从新创建。然而,如果intent的是B,一个新的实例会被加到栈顶,尽管他的启动模式是singleTop。

   singleTask

      系统创建一个新的task并且实例化在task根部的task。如果activity的实例早已存在在单独的task中,系统会找到这个实例,不会创建一个新的实例。在一个时间只能有一个activity的实例存在。

   SingleInstance:

      和singleTask同样,只是系统不会启动其他的实例在task中。Activity总是单例的,task中的唯一成员。启动的活动在单独的task中打开。

  

   举另一个例子,安卓浏览器声明:web 浏览器activity应该总是在他自己的任务中打开-在<activity>中 声明singleTask启动 模式。这意味着如果你的app发出一个intent打开浏览器,浏览器中 的activity是不会放在你的app中的。而是,要么一个 浏览器的新的task被启动,或者如果浏览器的task早已经在后台运行了,这个任务会进一步处理新的intent。

 

   无论是否一个activity在一个新的task中启动还是在同一个任务中,back按钮总是把用户带到前一个activity。然而,如果你启动一个指定了singleTask启动模式的activity,然后如果这个activity的实例已经存在了在一个后台任务中,那么拥有这个实例的整个任务都会被带到前台。图片4展示了这种场景。

 理解任务和返回栈

 

如果想了解更多,看一下activity元素的文档:

 

多谢大家支持。