Android浅谈任务和返回栈

(…..咳咳, 别点了,上面这个只是一个截图而已. @_@! )

原文来自:Google Android developer by lan Lake —— Tasks and the Back Stack

当我们点击了launcher桌面上App应用程序实际上发生了什么呢?如果你说“我的应用程序启动起来了”,你在技术上是正确的,也是在所有回答类别中最佳的一个.如果我们在深入一点,我们利用返回这件小事情去看看,它对我们理解什么是任务以及它是如何去交互的会有帮助的

任务

一个任务是围绕着一个活动栈元数据和信息的集合(你可以查看RecentTaskInfo类获取更准确的数据)。

所以当你点击了launcher桌面上你的App应用程序,系统其实会开始去上一个已经存在的任务(通过Intent意图和Activity活动来指向确定) 去恢复—— 然你回到你该回到的地方.如果任务中没有存在可以被发现,然后利用最新启动的Activity作为基类Activity,一个新的任务就在任务的返回栈里被创建了。

返回栈

你或许会想象,返回键一个任务的返回栈是捆绑在一起的,但是它是双向的,当你开始利用startActivity()启动一个新的activity,将会(默认情况下)推送出一个新的activity在你的任务之上,原因是上一个Activity 已经被暂停了(如果这个新的activity完全掩盖了上一个activity,就被停止了)。

a simple back stack

当操作返回键时(默认情况下)然后会‘抛出’任务,在最顶端的activity将会调用finish(),销毁它并且从返回栈中移除,同时带你返回上一个activity。重复这样操作直到在返回栈中不会留下任何东西了,你也就将回到launcher桌面上了。

返回栈和Fragments

返回栈不是仅仅用于activity上:它也应用于fragments。当你提供一个fragment transaction从你的用户界面去添加,替换,或者移除一个fragment,你能够使用addToBackStack()去有效添加FragmentTransaction到你的返回栈

当你使用这种方式,返回键被点击中,FragmentTransaction 将会被反向(一个添加的fragment被移除,一个替换的fragment被还原,或者一个被移除掉的fragment被重新添加)。每一个事务被添加到返回栈是被反向翻转的,直到默认的activity被finish结束的那个时候,它们所有才会被移除,再次放进来将会重复表现。

返回不是唯一的导航键

当然,在一个现代化的Android设备里(我们不去过多的讨论有关menu button相关的东西)返回键不是唯一的导航键。

home 键可能是最简单的,它是单焦点:它放置当前任务到后台,然后带着你回到你的launcher桌面上。

笔记:移动你的任务到后台,不会杀死你的任务(虽然最顶端的activity肯定被暂停+被停止): 它将一直存活直到Process(进程)被杀死。在‘Who lives and who dies ?(谁活着,谁灭亡?)这篇博客优先学习更多有关进程和什么时候你的app应用会被杀死。

overview 键(最近任务),带领你,你或许会想象,对于Overview screen,这是在Android世界里的’应用程序切换器’—— 在这儿你将会看到你最近的任务,也能够选择其中的一个带它返回到前台。

##好了,就是它们这些了,没有更多可以看的了
梳理一下,startActivity()或addToBackStack()返回键默认的特性。这儿没有什么特别的,但没有任何混淆 —— 这些对称,一致的行为作为默认。在多数情况下,你应该使用这些默认的特性

在你直接运行和复写onBackPressd()之前,这儿有一些特殊的情况你或许要去是考虑一下:

防止返回键疲劳过度

当然,当你需要按10+次走出你在哪里,返回按钮会失去了一些光泽,另一种情况,当你启动的是当前同一个activity,这是很容易避免的,

创建一个任务多个复制相同Activity,(无论是从内存压力还是返回键疲劳过度都一起减少了)你的Activity能够在AndroidManifest使用launchMode=”singleTop”或者你能够在你的Intent意图里添加Intent.FLAG_ACTIVITY_SINGLE_TOP

在顶部返回栈防止同一个activity拷贝多个副本,利用new Intent 和任意的extras你将会在onNewIntent()中得到一个回调。

笔记:在读onNewIntent()文档时小心:getIntent()将一直返回原始的Intent除非你使用setIntent()去重写它

返回栈和通知

如果你将在你的应用里构建一个通知指定一个Activity,这里有一种情况要避免:点击返回键直接回到launcher桌面上。当你利用一个基本的activity提供一个PendingIntent开启一个新的任务会出现这种情况,除非你的通知是打开你的启动activity,这不是你想要的。如果它们作为导航到应用本身重新的那一部分,用户应该是明确目标地点的,你的通知仅仅是保存了它们的中间步骤。

对于某些事情是如此的重要,有一个类它将会为你完成所有的任务这将是非常好的。进入TaskStackBuilder: 一个处理标志和返回栈的特殊类,对于你对于这种情况:

// Construct the Intent you want to end up at

Intent detailActivity = new Intent(this, DetailActivity.this);

// Construct the PendingIntent for your Notification

TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);

// This uses android:parentActivityName and

// android.support.PARENT_ACTIVITY meta-data by default

stackBuilder.addNextIntentWithParentStack(detailActivity);

PendingIntent pendingIntent = stackBuilder

  .getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);

你将在使用addNextIntentWithParentStack()方法时注意 —— 这个方法在正常Intent意图,你将创建了一个PendingIntent去构建一个完整的任务栈刚好通过的捷径。虽然它有一个要求:每一个activity需要有一个它的父activity定义在Androidmanifest(从这篇文档中看示例代码)。

如果在你情况下默认不工作,你不需要抛出TaskStackBuilder:editIntentAt()允许你回收一个特殊的Intent意图并设置action动作,设置data URL数据地址,或者add extras传一个值。如果你需要甚至更多的定制,你可以放弃使用*ParentStack()方法完全直接使用 addNextIntent()添加确切你需要的Intent到你的具体情况

笔记:如上所述在文档里,对于其他类型的activity你或许从一个特殊的notification通知(i.e,没有在你正常的应用重新流程下的一个通知)去启动。这个或许是一个例子,环聊的(Hangout’s)直接回复像一个activity在Android N之前。这些acitivities是通常半透明 —— 你能看到其他的app应用程序在你的activity下面 —— 同时一般没有任何返回栈合成或者新的任务和它们关联。

任务和返回栈,一起工作

记住这个部分已经被预测很重要,如果将是使用你的返回栈乱搞,请确保测试非常彻底,以确保最佳的用户体验。

android developer patterns

翻译有限,不足之处,欢迎指正

0%