[原]Android学习之 Activity堆栈管理与控制

[原]Android学习之 Activity堆栈管理与控制

App程序中有很多Activity、你可以通俗的理解为把一个Activity看做是一个UI界面。在Andord系统中Activity是以堆栈<堆栈的特性:只有压入和弹出  先进后出>的形式存在。堆栈中的根Activity就是应用程序的启动Activity。而堆栈中最上方的Activity则是当前运行的/用户正在操作的UI Activity。

    也可以这样去理解:堆栈中保存的是Activity对象,如果一个应用中多次使用了一个Activity,那么就会使同一个任务中出现多个该Activity的对象。一个程序在运行、他所启动的Activity通常情况下<注意是通常情况下>在同一个堆栈中、这个也叫做任务栈<Task>。

    Activity和Task的关联: Activity在任务中的行为,受控于启动Activity的行为对象的标志位和清单文件中的<activity> 元素的属性的互相作用。

    

主要的行为标志有:

FLAG_ACTIVITY_NEW_TASK 

FLAG_ACTIVITY_CLEAR_TOP 

FLAG_ACTIVITY_SINGLE_TOP

..............等


主要的<activity>属性有:

launchMode 

taskAffinity 

allowTaskReparenting 

alwaysRetainTaskState

clearTaskOnLaunch 

finishOnTaskLaunch


下面将对每一个属性和标志一一介绍:

[虽然全是文字说明,稍有枯味、但只要你细细消化 相信使你对Activity栈的管理会进一步理解]

<activity>属性:

1、launchMode:Activity 4种启动模式  

     1>、standard: <默认启动模式>

           在任务栈中总是创建一个新的Activity实例

     2>、singleTop:

           在任务栈中如果有存在一个和新启动Activity相同的Activity正在栈顶则不再创建一个新的Activity,即不再调         用onCreate(),而是通过调用onNewIntent()方法。如果不存在栈顶,这时候就和standard一样创建一个新的             Activity实例,走onCreate()方法。

      3>、singleTask:

             ①设置了"singleTask"启动模式的Activity,它在启动的时候,会先在系统中查找属性值affinity等于它的属性        值taskAffinity的Task存在;如果存在这样的Task,它就会在这个Task中启动,否则就会在新的任务栈中启动。        因此,如果我们想要设置了"singleTask"启动模式的Activity在新的任务中启动,就要为它设置一个独立的taskAffinity属性值。

            ② 如果设置了"singleTask"启动模式的Activity不是在新的任务中启动时,它会在已有的任务中查看是否已经        存在相应的Activity实例,如果存在,就会把位于这个Activity实例上面的Activity全部结束掉,即最终这个Activity 实例会位于任务的Stack顶端中。

            ③ 在一个任务栈中只有一个”singleTask”启动模式的Activity存在。他的上面可以有其他的Activity。这点与singleInstance是有区别的。

       4>、singleInstance:

             在一个新的任务栈中启动,且该栈中有且只有他一个Activity实例、不允许有其他的Activity成员存在。

             永远他一个。


2、android:taskAffinity: task亲和力

      通常来说一个程序内/任务栈中的Activity具有亲和力,也就是说具有相同亲和力的Activity默认属于同一个任务Task中,

     affinity决定两件事情——Activity重新宿主(从一个Task跳到了另一个Task中,新的Task就被称为重新宿主)的Task(参考allowTaskReparenting特性)和使用FLAG_ACTIVITY_NEW_TASK标志启动的Activity宿主的Task。

     默认情况,一个应用程序中的所有Activity都拥有相同的affinity。你可以通过设定这个特性来重组它们,甚至可以把不同应用程序中定义的Activity放置到相同的Task中。如果不指定改activity到底属于哪个task,则可以将affinity设置为空字符串。如果这个特性没有设置,Activity将从应用程序的设定那里继承下来(参考<application>元素的taskAffinity特性)。应用程序默认的affinity的名字是<manifest>元素中设定的package名。

      注意:affinity只有在加载activity的Intent对象包含了FLAG_ACTIVITY_NEW_TASK 标记,或者当activity的allowTaskReparenting属性设置为“true”时才有效。


3、android:allowTaskReparenting:是否允许Activity跳转/更改Task

     用来标记Activity能否从启动的Task移动到有着相同affinity的Task(当这个Task进入到前台时)——“true”,表示能移动,“false”,表示它必须呆在启动时的那个Task里。如果这个特性没有被设定,设定到<application>元素上的allowTaskReparenting特性的值会应用到Activity上。默认值为“false”。

      一般来说,当Activity启动后,它就与启动它的Task关联,并且在那里耗尽它的整个生命周期。当当前的Task不再显示时,你可以使用这个特性来强制Activity移动到有着affinity的Task中。典型用法是:把一个应用程序的Activity移到另一个应用程序的主Task中。


4、android:alwaysRetainTaskState:当按下Home主键将程序退回至后台运行,再回到前台时是否保留Task状态

     用来标记Activity所在的Task的状态是否总是由系统来保持——“true”,表示总是;“false”,表示在某种情形下允许系统恢复Task到它的初始化状态。默认值是“false”。这个特性只针对Task的根Activity有意义;对其它Activity来说,忽略之。

     一般来说,特定的情形如当用户从主画面重新选择这个Task时,系统会对这个Task进行清理(从stack中删除位于根Activity之上的所有Activivity)。典型的情况,当用户有一段时间没有访问这个Task时也会这么做,例如30分钟。

然而,当这个特性设为“true”时,用户总是能回到这个Task的最新状态,无论他们是如何启动的。这非常有用,例如,像Browser应用程序,这里有很多的状态(例如多个打开的Tab),用户不想丢失这些状态。系统会为我们保持这些状态数据。


5、android:clearTaskOnLaunch:当按下Home主键将程序退回至后台运行,再回到前台时是否清除/移除除了跟Activity<启动Activity>之外的所有Activity。

     用来标记是否从Task中清除所有的Activity,除了根Activity外(每当从主画面重新启动时)——“true”,表示总是清除至它的根Activity,“false”表示不。默认值是“false”。这个特性只对启动一个新的Task的Activity(根Activity)有意义;对Task中其它的Activity忽略。

    当这个值为“true”,每次用户重新启动这个Task时,都会进入到它的根Activity中,不管这个Task最后在做些什么,也不管用户是使用BACK还是HOME离开的。当这个值为“false”时,可能会在一些情形下(参考alwaysRetainTaskState特性)清除Task的Activity,但不总是。

    假设,某人从主画面启动了ActivityP,并从那里迁移至Activity Q。接下来用户按下HOME,然后返回Activity P。一般,用户可能见到的是Activity Q,因为它是P的Task中最后工作的内容。然而,如果P设定这个特性为“true”,当用户按下HOME并使这个Task再次进入前台时,其上的所有的Activity(在这里是Q)都将被清除。因此,当返回到这个Task时,用户只能看到P。如果这个特性和allowTaskReparenting都设定为“true”,那些能重新宿主的Activity会移动到共享affinity的Task中;剩下的Activity都将被抛弃。


6、android:finishOnTaskLaunch:当按下Home主键将程序退回至后台运行,再回到前台时是否关闭/结束掉退回到后台之前的Activity.

     用来标记当用户再次启动它的Task(在主画面选择这个Task)时已经存在的Activity实例是否要关闭(结束)——“true”,表示应该关闭,“false”表示不关闭。默认值是“false”
如果这个特性和allowTaskReparenting都设定为“true”,这个特性胜出,Activityaffinity忽略。这个Activity不会重新宿主,但是会销毁。



通过Intent设置的属性标识:

形式如下:

Intent intent = new Intent(SwitchActivity.this, ThredActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);


1、FLAG_ACTIVITY_NEW_TASK

     在默认情况下,一个新Activity被另一个Activity调用了startActivity()方法,载入任务之中。并压入了调用者所在的堆栈。然而,如果传递给startActivity()Intent对象包含了FLAG_ACTIVITY_NEW_TASK标记,系统会为新Activity安排另外一个任务。一般情况下,如同标记所暗示的那样,这会是一个新任务。然而,这并不是必然的。如果已经存在了一个与新Activity有着同样affinity的任务,则Activity会载入那个任务之中。如果没有,则启用新任务。

简言之:有相同affinity的任务,则压入该任务,否则创建一个新的任务。


2、FLAG_ACTIVITY_CLEAR_TOP

      如果intent将要启动的Activity已经存在于一个Task中,那么这个Task中该Activity上面的那些Activity都会被移除销毁,然后这个intent将会作为一个新的intent投递给目标Activity(目标Activity已经位于栈的顶端了)。

     这个启动模式还可以与FLAG_ACTIVITY_NEW_TASK结合起来使用:用于启动一个Task中的根Activity,它会把那个Task中任何运行的实例带入前台,然后清除它直到根Activity。这非常有用,例如,当从NotificationManager处启动一个Activity


3、FLAG_ACTIVITY_SINGLE_TOP

     如果设置,当这个Activity位于历史stack的顶端运行时,不再启动一个新的。
     同 android: launchMode = “singleTop”


4、FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS

     如果设置,新的Activity不会在最近启动的Activity的列表中保存。


以上只介绍了常有用的几种控制Activity跳转的Flag标识

更多详细前往 http://android.toolib.net/reference/android/content/Intent.html 进行学习。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值