Activity 和 task 的设计择要
- Activity 是 Android 应用的首要构成项目组。
- 除了本身写Activity之外,你还可以哄骗intent,轻松地重用其它应用的Activity。
- 你可以让你应用里的Activity能被其它应用经由过程intent应用。
- 体系的Activity栈几乎可以处理惩罚所有的景象。不过有两种景象你可能须要本身设置flag之类,来断定the right thing happens。
在本文档中
- Applications,Activity,Activity栈和Task
- Activity和Task的一个例子
- 从主屏开端一个Activity
- 分开一个Activity
- 重用一个Activity
- 调换Activity
- 多Task
- 从两个进入点启动应用
- Intent
- 在Task之间切换
- 设计建议
- 若是你不想你的Activity被重用,不要应用intent filter
- 重视处理惩罚用intent找不到activity的景象
- 推敲启动应用的体式格式
- 容许Activity参加到当前Task中来
- Notification应当让你的用户很轻易分开
- 应用Notification体系
- 若是不是绝对须要,不要本身把握BACK键
参考
- Application根蒂根基
这个文档,从高层的、以用户为中间的视角,描述了Android应用框架的 核心原则。这对交互和应用设计者和应用开辟者是有效的。
本文用多个例子说了然Activity和Task,并且描述了一些它们的底层原则和 机制,像导航,多Task,Activity重用,Intent和Activity栈。 文档还夸大了一些你能用到的设计结论,和你如何把握你应用的UI。
这个文档应用了很多Android应用作为例子,包含一些默认应用, 例如Dialer,以及Google应用,例如Maps。你可以在你的Android模仿器 或者Android的手机上尝尝它们。重视你的手机或许只供给一项目组这些文档 中的例子应用。
在设计建议项目组中,会提到一些原则、 建议、和要避免的工作。Application根蒂根基覆盖了法度的底层 机制,本文档是对它的补充和完美。
Applications,Activity,Activity栈和Task
以下四个根蒂根基概念有助于你的懂得:
- Application
- Activitie
- Activity栈
- Task
Application
一个典范的Android Application由一个或多个相干的、松耦合的、用户可以 与之互动的Activity构成。典范的景象,是一个Application打包进 一个零丁的apk文件里。Android会伴跟着一大票的应用,可能包含电子邮件、日历、浏览器、地图、 短信、接洽人、摄影、拨号、音乐播放、设置等等。
Android主屏一般就是应用启动者。一般来说,是一个有很多应用图标的滑动抽屉(就是默认Android体系下面那个,用手指往上一拖就呈现很多图标的那个器材。),用户可以从上方启动应用。
Activity
Activity是Android应用的首要构成项目组。 当你建树Apllication的时辰,你可以本身建树的Activity或者重用其它Application的Activity,来组装Application。 这些Activity是在运行时绑定在一路的,所以,新安装的Application能从已安装的Activity中获益。 一旦组合在一路,这些Acitivity会像一个整体那样一路工作。 一个Activity拥有一个自力的可视UI,这个UI应当基于零丁的、明白界定的意图。 例如看图、编辑、拨号打德律风、摄影、搜刮、发送数据、语音号令等等其他用户行动。 一个须要界面显示的Application至少要有一个Activity。
当应用一个Android设备时,用户会从一个界面跳到另一个界面,这种跳转应当是流畅的。 不该该让用户察觉那些底层的行动,比如Activity间或者Task间的切换。
一个Activity持有了一种特定种类的内容(数据),以及接管一系列相干的用户动作。 一般来说,每个Activity的生命周期,与其他的同一个Application或Task内的Activity是无关的。 每一个Activity自力地被运行,用户或者体系可以按须要start、run、pause、resume、stop或者restart这些Activity。 因为这种自力的特点,有很多种办法可以覆盖或者重用Activity。
Android供给的拨号法度就是一个Activity组合的例子。这个法度是由4个Activity组合成的: 拨号,接洽人列表,接洽人详情,和新建接洽人。如下所示:
下面是一些其它的由多个Activity组合的Application的例子:
- 电子邮件 - 查看目次、查看消息列表、查看消息、写消息、设备账号。
- 日历 - 查看日、周、月、规划,编辑时候,设置属性,提示
- 摄像摄影 - 运行拍照机,看图片列表,看图,切图,运行摄像机,看视频列表,看视频
- 游戏 - 游戏本身,以及安装设置
- 地图 - 查看当前地位,列表(turn list或者石友列表),具体材料(石友地位、状况、照片)
Activity,是构成Application的四种组件中,最首要的一个。别的的组件是, Service,ContentProvider,BroadcaseReceiver。更多关于Activity的细节,请参考 Application组件中的Activity项目组。
Activity栈
当用户在Application中,从一个Activity跳到另一个时,Android体系会 保存一个用户接见Activity的线性导航汗青。 这就是activity栈,也被称为返回栈。 一般来说,当用户运行一个新的Activity,这个Activity就会被加到Activity栈里。是以,当用户 按BACK键的时辰,栈中的上一个Activity就会被显现出来。 用户可以一向按BACK键,直到返回到了主屏。 The adding of an activity to the current stack happens whether or not that activity begins a new task (as long as that task was started without going Home), so going back can let the user go back to activities in previous tasks. 把Activity参加到当前栈里的操纵,与Activity是否启动了一个新Task无关。 返回操纵可以应用户从当前Task回到上一个Task。 用户可以在应用经管器、主屏、或者“比来Task”屏幕,恢复到方才的Task。
只有Activity可以加到Activity栈里去,其它的,包含View、Window、Menu或者Dialog都不可。 这就是说,假设,界面A跳到界面B,然后用户可以用BACK跳回界面A。这种景象下,A和B都要被实现成Activity。 这个规矩有一个例外的景象。那就是除非你的应用 把握了BACK键并且本身经管界面导航。
Task
一个Task是用户可以完成一个特定目标的一组Activity。与Activity属于哪个Application无关。 除非明白地新建一个Task,(参考打断Task),用户启动的所有Activity都默认是当前Task的一项目组。 须要重视的是,这些Activity可能属于任何一个Application — 属于同一个Application或者属于不合的Application。 这就是说,一个Task可所以,从接洽人列表开端,然后选择一个邮箱地址(经由过程电邮Activity),然后附加一个照片(经由过程图片Activity)。 接洽人列表、电邮、图片,这些都存在于不合的Activity中。
启动Task的Activity被称作根Activity。 凡是,Task是从应用经管器、主屏或者比来Task(长按HOME键)开端的。 用户可以经由过程点击根Activity的图标回到Task里去,就像启动这个Activity一样。 在这个Task中,BACK键可以回到这个Task的前一个Activity里。 Activity栈可以由一个或多个Task构成。
一些关于Task的例子:
- 发送一个有附件的短信
- 看YouTube,然后经由过程Email分享这个视频
打断Task - Task的一个首要的特点就是,用户可以中断他当前正在做的事(他的任务),去进行另一个Task,然后可以返回到本来的那个Task去完成它。 这个特点的意图,就是用户可以同时运行多个任务,并且可以在这些任务间切换。 有两种首要的的办法分开一个Task,这两种景象中,应当让用户可以或许返回到他们分开的那个任务:
- 用户被Notification打断 – 来了一个通知,用户开端存眷处理惩罚这个通知
- 用户决意开端另一个任务 - 用户按了HOME键,然后开端了另一个Application
当然,规矩老是有例外。除了上方提到了两种办法,确切存在第三种办法开端一个新任务,即,在代码中startActivity的时辰,定义它要开端一个新Task。 地图和浏览器两个应用就是这么做的。 例如,在电邮中点击一个地址,会在新Task调出地图Activity,在电邮中点击一个链接,会在新的Task中调出浏览器。 在这种景象下,BACK键会回到上一个Activity(另一个Task中的电邮Activity),因为它不是从主屏启动的。
Activity和Task的一个例子
接下来的例子,说了然Application、Activity、Activity栈、BACK键、Task和Intent的基起原根蒂根基理。 它显现了体系响应用户操纵的体式格式,包含启动Activity和在Task之间切换。 你可以在你的Android手机上,遵守下面指导的那样,履行这些例子。
从主屏启动一个Activity
主屏是绝大项目组Application启动的处所。(某些应用只能从其它应用进入。) 当用户点击应用经管器的一个图标(或者主屏上的一个快捷体式格式),这个应用的主Activity会被启动到前台,并拥有效户的核心。 像下面图标显现的那样,用户进入主屏并点击电邮图标的行动,启动了电邮Application的消息列表Activity。 主屏Activity被置到后台,stop。当用户从头进入主屏时,restart。
按着Activity导航,经由过程BACK键和HOME键分开Activity
一个Activity是否对峙它的状况,取决于用户分开它的体式格式 - 是经由过程HOME键还是BACK键。
默认景象下,按BACK键会finish(destroy)当前Activity,然后显示上一个Activity给用户。 鄙人面的图中,用户经由过程在主屏点击电邮图标启动了显示出电邮消息列表的电邮应用。 用户迁移转变列表(改变了初始状况)。 点击BACK键烧毁了消息列表Activity,然后回到了上一个Activity,便是主屏。 用户从头启动电邮应用后,电邮应用显现出来的列表,是从头初始化,没有经过迁移转变的。
在上方的例子中,按BACK键会回到主屏,是因为主屏是用户能看到的最后一个Activity。 如果用户是从其它Activity进到消息列表Activity的,那么按BACK键会回到来的处所。
作为对比,下一个图表显现了用户用HOME键而不是BACK键来分开消息列表Activity的景象 - 消息列表Activity会stop然后移到后台,不会被烧毁。从快捷体式格式从头启动电邮Application,会把后台的这个应用 置到前台(从stop变成running)。迁移转变状况会跟用户分开的时辰一样。
有例外景象。 某些后台Activity回到前台后,会进到它的初始界面(而不是分开时的状况)。 接洽人应用和看图应用就是这种Activity。 当用户从主屏进入接洽人应用,然后选择一个接洽人看具体材料。(然后HOME键)。 若是用户再次从主屏进入,就会回到接洽人列表而不是分开时的具体材料。 如许设计接洽人应用,是因为接洽人列表是全部应用4个Tab的主进入点。
别的,不是所有的Activity都邑在按BACK的时辰被烧毁。 当用户应用音乐应用播放音乐,然后按BACK键时,应用重写了撤退猬缩的行动,Activity没被烧毁,而仅仅是变得不成见。(所以保存了状况)。 音乐持续播放,并呈现一个Notification,让用户可以回到音乐Activity去把握音乐的播放。 重视,你可以写不成见就烧毁的Activity,也可以写像音乐Activity一样仅仅会切到后台的Activity。
重用一个Activity
假设Activity A启动了另一个Application中的Activity B,就说Activity B被重用了。 在Activity A广播查找才能然后B有这个才能时,这种景象就会产生。
Contacts重用了Gallery来取图片 - Contacts Activity有一块区域用来显示接洽人的图片,而一般来说,所有的图片都保存在Gallery里。 于是Contacts可以重用Gallery Activity来取图片。 这是一个重用Gallery Activity的很好的例子。 下面的图表说了然这个流程(首要项目组)。 流程是如许的:用户点击Contacts,然后点选一个接洽人查看具体材料,按MENU键,编辑接洽人,点击图片区域, 于是就会启动Gallery Activity。用户找到想要的图片后,裁剪并保存。保存这个动作,会导致图片被插入到接洽人详情的图片区域中。
Gallery会返回图片给启动本身的Contact Application。 下面一个例子说了然重用Activity但没有返回的景象。 还要重视下面的图标是一个对Activity导航汗青(即Activity栈)的申明。用户可以一向按BACK直到回到主屏。
设计Application的时辰,推敲如何可以或许重用其他Application中的Activity, 以及推敲本身的Activity如何被其它Application重用,是一个很好的思路。 若是你的Activity拥有一个和已存在的Activity一样的Intent Filter, 体系会供给给用户一个对这些Activity的选择界面。
Gallery重用Messaging来分享图片 - Sharing is 分享图片是另一个很好的关于在不合的Application重用Activity的例子。 如下图所示,用户启动Gallery,选一个图,按MENU键,选Share,选Messaging。 这就会启动Messaging Activity,然后建树一个新的消息并把图片附在上方。 然后用户填写“收件人”、写个短消息然后发送。 用户的存眷点如今在Messaging法度上。 若是用户想回到Gallery,他必须按BACK键。(用户可以经由过程BACK键从任何一个Activity一路返回到主屏。)
与上一个例子不合,这个对Messaging Activity的重用什么都没有返回给启动它的Gallery Activity。
两个例子实际上都说了然Task — 为了完成一个目标的一系列Activity。 每个例子都是用了来自不合的Application的Activity来完成任务。
庖代一个Activity
下面这个景象,是Activity A在不合的Application里庖代了Activity B。 这种景象一般产生在Activity A做某项工作比Activity B好的时辰。 换句话讲,A的功能足够庖代B。 与重用不合的是,重用的时辰,A和B做的是不合的工作。
在本例中,用户下载了一个PhoneRingtone Activity的调换品,叫做RingsExtended。 如今,当用户进入Setting,SoundDisplay,PhoneRingtone,体系会供给一个选择界面,让用户选择是应用Android体系的德律风铃Activity还是新的这个。 这个对话框有一个多选框,让用户可以选择“这种景象下默认应用这个选项”。 用户选了RingsExtended,然后新的Activity被启动,庖代了本来的Android体系德律风铃Activity。
多Task
上方说过,用户可以从一个Activity经由过程HOME切到主屏,然掉队入另一个Activity,而前一个Activity不会被烧毁。 下面演示了进入Map Application的景象。
- State 1 - 用户进入ViewMap Activity,搜刮一个地址。假设收集很是慢,应用须要异常长的时候来搜刮。
- State 2 - 用户想在守候的时辰做一些其它工作,所以他按HOME键,分开Map,然则没有打断收集连接。如今Map在后台持续工作。
重视,你可以本身决意,在法度被挪到后台后,是持续运行还是停止。 (参考onStop(),Activity生命周期)。 对于从收集高低载数据这类Activity来说,建议还是让它们在后台的时辰,持续工作。用户就可以多任务了。
- State 3 - 如今,Map Activity在后台运行了。主屏到了前台。 然后,用户运行Calendar Activity,把Calendar置到前台。如今用户存眷Calendar,并浏览今天的日程。(如图中粗线所示)
- State 4 - 用户按HOME键,然后点击Map,回到Map Activity,看到地图已经读取完了。
主屏的应用启动器,在两个不合的Task里,启动了ViewMap和DayView两个Activity。 这个时辰,体系就是多任务的 — 运行了多个Task。
Launching Two Entry Points
每个Application必须至少有一个进入点 — 好让体系或者用户进到Application的Activity里。 在主屏的ApplicationLauncher,每一个图标默示了一个进入点。 Application也可以从其他Application进入。 每个Activity都是一个Application的潜伏进入点。
Android供给的PhoneApplication有两个进入点:Contact和Dialer。 一个在Contact中的用户可以点选一个德律风号码,来进入Dialer。 如下图所示,用户能点击Contact的图标来进入ContactActivity,然后点击一个德律风号码,来进入DialerActivity,拨打德律风。
一旦用户进入到了Application里,就可以经由过程tabs、menu items、list items、buttons或者其他界面把握元素, 来进入其它的Activity,例如NewContact或者EditContact之类。
Intent
当用户要对某类数据做出行动时,例如,点击一个mailto:info@example.com链接, 他们实际上是初始化了一个Intent对象(一个Intent)。这个Intent会被解决成为一个特定的Commpnent。 (这里我们只说ActivityComponent)。 (翻译成人话:用户要做一件工作,实际上会初始化出来一个Intent,广播询问体系,然后终极导致一个特定的Activity被调用。) 进而,用户点击mailto:链接的成果,是一个Intent对象。体系会测验测验用这个Intent来匹配一个Activity。 若是这个Intent明白地指名了一个Activity(一个明白Intent),体系会立即进入这个Activity来响应用户动作。 然而,若是这个Intent没有指名Activity(一个不明白Intent),体系会斗劲这个Intent和所有可用的Activity的IntentFilter 。 如果多个Activity都能处理惩罚这个动作和数据,体系会让用户选择一个。
下图显现的就是点击mailto:链接的例子。 若是设备上有两个处理惩罚Email的应用,当用户点击电邮地址的成果,是呈现一个对话框,让用户在两个应用中心选一个。(Gmail和Email两个应用)。
Here are some examples of Intent objects and the activities they resolve to: 这里是一些Intent对象(不明白的)和Intent对应Activity的例子:
- 看接洽人列表 - resolves to a contact list viewer activity
- 看特定接洽人 - resolves to a contact viewer activity
- 编辑特定接洽人 - resolves to a contact editor activity
- 向一个特定地址发电邮 - resolves to an email activity
- 拨打德律风 - resolves to a phone dialer activity
- 看图列表 - resolves to an image list viewer activity
- 看图 - resolves to an image viewer activity
- 裁剪图片 - resolves to an image cropper activity
重视,Intent对象指定了两件事:行动和数据:
- 一个须要进行的行动。上方的例子中,看、编辑、拨号、裁剪都是行动。
- 要进行这种行动的特定的数据。上方的例子中,接洽人列表,特定接洽人,德律风号码,图列表,特定的图都是数据。
任何一个在主屏上启动Activity的Intent都是明白的Intent。 灵位,一些Activity进入本身Application内部的Activity应用的也是明白Intent。
Intent的详情,拜见Intent class
和 intent filters.
在Task间切换
下面一系列图显现了用户如安在两个Task间转换。 在这个例子中,用户写了一个文本消息,然后附上一张照片。在做这些事儿的时辰,用户看了一眼日历。 然后,用户回来,持续附照片和发送消息。
- 开端第一个Task。 为了发送一个附加了图片的消息,你须要如下操纵:
主屏 > Messaging > NewMessage > MENU > Attach > Pictures 最后一步操纵启动了Gallery来取照片。 重视到,Gallery是在别的一个Application中。
在用户取图之前,用户决意去看一眼日历,这就是另一个Task了。 然则当前界面没有一个直达Calendar的按钮,所以用户必须回到主屏去。
- 开端第二个Task。 用户按HOME键 > 点Calendar来看日历。 Calendar作为一个新的Task被启动。ApplicationLauncher启动的Application都是新的Task。
- 切换到第一个Task,并完成它。 看完了日历,用户于是按HOME键 > Messging,返归去持续附加图片。 这个操纵并没有应用户进入Messaging,而是进入了方才分开的Gallery(即使这两个并不是一个Application!)。 然后用户选择一个图片,参加到消息里去,发送消息,完成第一个Task。
设计建议
以下是对应用设计者和开辟者的建议和指导。
当你写的Activity不欲望被重用的时辰,不要写IntentFilter。应用正确的Intent来调用它。
当你不想你的Activity被其它Application重用的时辰,要断定这个Activity上没有定义任何的IntentFilter。 只能从应用经管器进入,或者只能从同一个Application进入的Activity,应当应用这种做法。 对于这类Activity,应用目标明白的Intent来进入。(而不是经由过程Intent向体系查询才能这种做法)。 这种景象,也没须要应用IntentFilter。 IntentFilter是公布给所有其它Application的。 所以,若是你用了IntentFilter,你实际上就是在给你的Activity参加了一个外部进口,有可能会造成无意识的安然漏洞。
当你重用其它应用的Activity时,不要忘怀处理惩罚没有Activity满足请求的景象。
你的Application可以重用其它的Activity,若是这些Activity可以重用的话。 重用的时辰,你不克不及假设你的Intent必然能匹配到一个外部Activity。你必须推敲没有合适Activity的景象。
你可以在真正启动Activity之前测试一下是否有匹配的,也可以直接启动Activity然后处理惩罚异常。 两种解决规划见博文Can I use this Intent?。
经由过程查询PackageManager可以知道一个Intent可否被匹配到一个Activity。 博文供给了一个例子,在isIntentAvailable()办法中。 然后,若是无法匹配,你可以停止机关Intent对象,或者再提示给用户一个地址,例如Market,让他去下载须要的应用。 如此,你的代码在调用startActivity()或者startActivityForResult()的时辰,可以包管Intent对象都是经过测试的并可以匹配到合适Activity的。
推敲你的Activity如何才干被其它Application重用。
一个设计者,或者开辟者,应当清楚用户可以如何启动你的Application,以及应用Application内的Activity。 用户可以经由过程主屏,或者其他Application来应用你应用里的Activity。
- 从主屏启动你的主Activity- 若是你的应用可以自力运行, 用户可能会从ApplicationLauncher(一般来说被实现成为主屏上的滑动抽屉), 或者主屏上的快捷体式格式,或是是TaskSwitcher,来启动它。 (这个机制,是对于IntentFilter的动作是MAIN分类是LAUNCHER的Activity。)
- 在其它应用内部启动你的Activity - 或许你的Activity是可以或许被重用的那种。 例如,很多Application可以或许用来和其它用户分享数据。 分享的体式格式包含电邮,文字信息或者把数据上传到某个公共网址。
当你的一个或多个Activity可以调换此外Application已存在的Activity时,在用户须要这个Activity时你可以让你的Activity也对用户可用。 例如,若是你的Activity也可以发送数据(电邮、文字信息或者上传),要推敲把你的这个Activity作为一个选择供给给用户。 给出一个特定的例子。Gallery让用户可以分享图片。 当用户从菜单选择“分享”时,体系会斗劲“分享”恳求(一个Intent对象)和可用的Activity(经由过程它们的IntentFilter),然后供给给用户来选。 此时,体系匹配到了Email,Gmail,Messaging和Picassa。 如果你的Activity也能发送图片或者上传图片的话,只须要经由过程设备IntentFilter让你的Activity可用就可以了。
其它Activity启动你的Activity的时辰,可能期望或者没有期望有返回。
- 期望有返回 - 这种景象是一个闭环,被启动的Activity必须或者返回一个断定值,或者被作废。 在上方那个从Gallery分享图片的例子里,用户完成了发送或上载操纵后,返回到了Gallery。 这个就是在Gallery中启动一个外部Activity的例子。 (经由过程
startActivityForResult()
启动的Activity就是如许)。 - 并不期望有返回 - 这种景象,是开放的。 以在邮件中点击地址为例,MapActivity会被启动来显示地图。 电邮并不须要Map来返回什么。用户可以经由过程按BACK来返回。 (经由过程
startActivity()
启动的Activity就是如许)。
- 期望有返回 - 这种景象是一个闭环,被启动的Activity必须或者返回一个断定值,或者被作废。 在上方那个从Gallery分享图片的例子里,用户完成了发送或上载操纵后,返回到了Gallery。 这个就是在Gallery中启动一个外部Activity的例子。 (经由过程
- 你的Activity仅仅能从其它Application内部启动。 - 上一个经由过程Email、Gmail、Messaging或Picass分享图片的例子中, 所有的Activity也都可以经由过程点击主屏上ApplicationLauncher上的图标来启动。 与之不合的是,用于裁剪图片并附加文件的Activity,不克不及从主屏启动。它们须要高低文运行景象,不克不及自力运行。
实际上,连Application都不是所有的都有图标并且可以在主屏启动的。 拿一个不常用的小应用做例子,这个小应用可以或许调换一个其它Application中有进入点的功能。 例如,Android一般有一个内建的铃声选择器,用户可以从设置应用中的声音设置来进入。 你可以写一个本身的铃声选择器,可以用跟体系的选择器同样的Intent来进入。 如下图所示,当用户选择“德律风铃”的时辰,会有一个对话框,来让他选择是应用体系的选择器还是你的选择器,用户可以保存他们的选择。 铃声选择器是一个不怎么常用,并且有一个已经明白定义的开端点(其它应用中)。所以,其实没须要在主屏弄一个零丁的图标给它。
- 一个Application有两个或多个主Activity,并且这些主Activity都有图标在主屏上。 - 我们已经定义了,零丁apk文件中的所有器材,都属于一个Application。 你可以写一个有多个主Activity的Application。
Camera.apk就是一个应用多个分隔的主Activity的很好的例子。它有两个主Activity,Camera和Camcorder, 有不合的图标,并且可以自力进入。 在用户看来,如同是两个不合的应用。 它们共享同一个镜头,并且都把数据(静态图片或者动态图片)存到Gallery里去。
In order for your application to contain two different, independent activities launchable Home, you must define them to be associated with different tasks. 若是你欲望你的应用包含两个能从主屏进入的不合的不相干的Activity,你须要定义它们接洽关系于不合的Task。 (意思就是说,要为每个主Activity设置不合的TaskAffinity。上方这个例子中,是“com.android.camera”和“com.android.videocamera”。)
Contacts和Dialer实际上也是这种景象,在同一个Application的两个主Activity。
- 把你的Application做成一个Widget - 一个Application也可以把它本身的一项目组作为一个AppWidget来显现,嵌入到主屏,或者其它的应用,并周期性地接管更新。
要容许你的Activity进入当前的Task。(而不是新建一个Task)。
若是你的Activity可以或许被其他Application启动的话,应当容许它们进入到当前Task, 或者一个有TaskAffinity的已经存在的Task。 让Activity可以或许被加到Task里去,可以让用户在包含你的Activity的Task和其它Task之间切换。 除非你的Activity只容许一个实例。
要达到这种结果,你的Activity的LaunchMode应当是standard或者singleTop,而不是singleTask或者singleInstance。 这些LaunchMode(standard或者singleTop)容许你的Activity有多个实例。
Notification应当可以或许让用户随便马虎地返回上一个Activity。
后台运行的应用,可以用一个Service来向用户发送Notification,让他们知道他们感爱好的事务。 Calendar和Email是两个例子。Calendar会发送Notification作为闹铃提示,而Email会发送Notification来提示用户新邮件。 建议,当用户在ActivityA,收到了一个Notification,经由过程这个Notification进入到ActivityB,再按BACK键时,应当回到ActivityA。
下面的流程显现了,当用户处理惩罚一个Notification的时辰,ActivityStack会如何工作。
- 用户在Calendar中新建一个提示事务,然后发明须要从某封电邮中复制些内容进来。
- 用户点击HOME > Gmail。
- 在Gmail里,用户收到了一个从Calendar来的Notification,提示他即速要开一个会。
- 用户选择这个Notification,于是用户进入了另一个CalendarActivity,这个Activity显示了这个会议的细节择要。
- 用户选择了这个提示,想看更多的细节。
- 看完这个事务后,用户按BACK键。回到了Gmail,便是他方才分开去看Notification的处所。
上述行动并不是必须的。
Notification一般来说经由过程下述体式格式之一来实现:
- 显现出来的Activity仅仅是为了Notification办事的。 - 例如,当用户收到一个Calendar的Notification,选择这个Notification会启动一个特别的Activity。 这个Activity显现了一个即将到来的事务的列表 — 这个视图仅仅是为了显现Notification用的, 在Calendar本身的UI中,没有进口。 当看完比来事务列表后,要包管用户可以经由过程BACK键往返到他刚才点击Notification时的Activity。
你应当包管这个专用的Activity的TaskAffinity与Calendar或者其它任何一个Activity的不合。 (要做到这一点,设置TaskAffinity为空字符串就行了,标示这个Activity跟任何其它任务无关)。 下面是申明。
因为Task的工作体式格式,若是这个专用Activity的TaskAffinity对峙默认的话,在上方的第6步按BACK键后, 会回到Calendar,而不是Gmail。 原因是,默认景象下,同一个Application的所有Activity有同一个TaskAffinity。 是以,这个专用的Activity的TaskAffinity会匹配第1步的那个Calendar的Task。 这意味着,选Notification会把已存在的Calendar事务(第1步的那个)拉到前面, 然后把这个专用Activity放到最上方。 这个不是你想要的。把这个专用Activity的TaskAffinity设成空字符串就能批改这个题目。
- 显现出来的Activity并不是专用的,然则一旦呈现到前台就是初始化状况。 - 例如,在响应Notification的时辰,当Gmail到前台,它老是会显示会话列表。 你可以经由过程把“clear top”flag放到notification的触发intent里来包管这个。 这种做法 - 启动Activity,这个Activity老是显现初始化状况 - 防止了当Gmail进入前台时处于用户分开时的状况。 (你可以把
FLAG_ACTIVITY_CLEAR_TOP
放到传递到StartActivity()的Intent来做到这一点)。
其它体式格式也可以用来处理惩罚Notification,包含把Activity拉到前台,显现特定的数据(显现方才收到新消息的文字消息线程)
一个Notification老是把Activity启动到新的Task。(Intent老是带着FLAG_ACTIVITY_NEW_TASK)。 这是因为,一个对当前任务的打断,不该该属于当前任务。
应用Notification体系 — 不要用Diaolog庖代Notification。
若是你的后台Service须要通知用户什么的话,应用标准的Notification体系 — 不要应用Dialog或者Toast来通知。 Dialog或者Toast会立即吸引用户的重视力然后打断用户,把他的重视力从他正在做的工作上吸引开: 用户可能正在输入文字,此时Dialog呈现的话,这些文字会被忽然应用到Dialog上。 用户习惯于在便利的时辰再处理惩罚你的消息和通知。
若是不是绝对须要,不要接管BACK键。
用户从一个Activity到另一个Activity的时辰,体系会把它们放到Activity栈里去。 这些以一个导航汗青的情势被BACK键哄骗。 大多半的Activity都有有限的目标,有单一系列的数据,例如看一批接洽人,写邮件,或者摄影。 然则,若是你的应用只是一个大Activity,此中有一些页,须要细粒度把握BACK键的时辰呢? 如许应用的例子,是浏览器和地图。Google浏览器有一系列的web页,Google地图有一系列的图层可以切换。 这两个应用都接管了BACK键,有内部的返回栈。
例如,Map应用了层在地图上来显现不合的信息给用户:显现地址搜刮的成果,显现伴侣的地址,显现两点之间的路线等。 Map本身储存了层的栈,所以BACK键可以回到上一层。
同样地,Browser应用浏览窗口显现不合的web页。 每个窗口有它们本身的导航汗青,类似桌面操纵体系中浏览器的Tab,每个Tab都有不合的返回栈。 For example, if you did a Google web search in one window of the Android Browser, clicking on a link in the search results displays a web page in that same window, and then pressing BACK would to the search results page. Pressing BACK goes to a previous window only if the current window was launched that previous window. If the user keeps pressing back, they will eventually leave the browser activity and return Home.