当前位置: 代码迷 >> Android >> 应用基础
  详细解决方案

应用基础

热度:26   发布时间:2016-05-01 15:39:07.0
Android Dev Guide 中文版一 (原创,转载请注明出处)未完待续

应用基础

Android 应用程序是用java语言编写。编译好的java代码、和系统所需要的数据和资源文件用aapt tool 工具打包成一个Andorid包。这个包文件是以.apk为后缀名的。这个文件包是在移动设备上分配和安装应用程序的媒介。它就是用户下载到他们设备上的文件,所有的代码都在一个单独的.apk文件被认为是一个独立的应用程序。

有很多方式,每个Android应用生存在他们自己的世界里:

  • 默认的,每个应用都运行在它们自己的linux进程中。当任何程序的代码需要执行其他程序时,Android就开始调用,当程序不在被需要,并且系统资源要回收的时候,这个应用程序就会被关闭。
  • 每个进程都有他自己的虚拟机,所以应用都单独的运行它们的代码。
  • 默认的,每个应用被分配一个唯一的linux用户ID。应用程序被设置许可,以保证应用文件只对本程序和本用户可用尽管也有其他的方式可以到处它们到其他应用中。

安排两个应用程序共享相同的用户ID可以有可能的。在这种情况下他们可以看见相互的文件。为了保护系统资源,拥有相同ID的应用程序会被安排在相同的linux进程,并且共享虚拟机。

应用组件

Android的一个核心的特性是一个应用可以用其他应用(这些应用必须提供了让其他应用访问它的许可)中的元素。例如,如果你的应用需要显示一个图片列表的滚动条,并且其他应用已经开发一个合适的滚动条并且提供这个滚动条给其他程序使用,那么你就能调用这个滚动条来工作,而不是自己开发。你的应用不会包括其他程序的代码或链接。恰恰相反它需要显示的时候仅仅是其他程序块。

对于这样的工作方式,当应用的任何一部分被其他应用说需要时系统必须能启动这个应用的进程。因此和其他大多数的系统的应用不同,Android应用中对于任何部分都没有一个单一的入口(例如没有main()函数)。恰恰相反的它有必不可少的组件,当系统需要时,系统可以实例化和运行这些组件回收。有四种这样的组件:

Activities
(编者译:activity可以理解为显示主页面,一些文本框,下拉框都布置在这个主页面上。这个主页面也是和用户的交互页面。)一个activity代表一个用户可以尝试操作的可视化用户界面An activity presents a visual user interface for one focused endeavor the user can undertake. 例如,一个activity 可以表示一个用户可以选择的菜单项目列表,可以显示一个带标题的图片。一个短信息程序可以有一个activity 显示要发送信息的联系人列表,第二个activitys可以写信息给选择的联系人。另一些activitys可以浏览旧的信息或者改变设置。通过它们一起工作来组成一个组合的用户界面。每一个activity都依赖于其他activity。每个都被实现implement为Activity基类的子类。
?
一个应用可以仅仅一个activity组成,它也由多个由像刚刚提到短信息程序或者显示标题的图片程序组成。activities是什么,它的多少取决于应用程序和它的设计。典型的当应用启动的时候activities 中的一个作为第一个展示给用户,从一个activity 转移到另一个activity 是由当前的activity 启动下一个activity 来完成的。
每一个activity 会被会一个默认的窗口来设计。典型的,窗口填充屏幕,但是他可以比屏幕下,并且可以浮动在其他窗口的上面。一个activity 也可以用其他另外的窗口-例如为了用户的响应在activity的中部调用弹出对话框。或者当用户在屏幕上选择一个特定的项目窗口会显示用户的重要信息。

窗口的可视化组件提一个视图对象的继承。这个对象由View 类起源。每个视图控制窗口中一个特殊的长方形空间。父类视图包括内容和安排其子类的布局。叶子视图(继承关系的最底层)在它们控制的矩形和直接响应用户动作的空间中描绘。因此视图是在用户发生activity的交互的地方。例如一个视图可以显示一个小的图片并且发起一个动作当用户点击这个图片。Android有许多的你可以用的只读视图,包括按钮,文本框,滚动条,菜单,选择框等。

一个视图的继承关系是放置在activity的窗口通过Activity.setContentView() 方法。内容视图是View对象的关系的顶部。(See the separate User Interface document for more information on views and the hierarchy)

服务 Services
服务没有可视化用户界面,相反的无限期的运行在后台。例如,服务可以运行背景音乐当用户处理其他事情的时候。或者它也可以通过网络获取数据,或者收集数据并提供给用户界面所需要结果。每个服务都扩展Service基类。一个初级的例子:一个媒体播放器在意播放列表中播放音乐。这个播放器引用可以有一个或者多个activities ,activities 包括允许用户选择音乐,并开始播放它们。然而音乐运行在后台而不能用户界面处理,因为用户希望音乐继续播放当他们离开这个播放器做其他事情的时候。为了保证音乐播放,这个播放器页面能启动一个服务来在后台运行。当离开播放页面的时候系统可以保证音乐播放服务运行

我们可以连接到一个正在运行的服务(可以启动一个没有运行的服务)。当连接时,你可以通过服务暴露的接口和服务进行通讯。对于音乐服务来说,这个接口有可以允许用户暂停,回放,停止,重启播放。

像activities 和其他的组件一样,服务运行在应用进程中线程的main函数。他们将不会阻挡其他组件,他们经常为费时的任务(如音乐播放)产生其他线程。看进程和线程。

广播接收者
广播接收者是一个只用来接收和相应广播通告的组件。需要广播产生于系统代码-例如,时区变更的通告,电量低的通告,图片被获取的通告,用户变更语言的通告。应用程序也能产生广播-例如让其他应用知道一些被下载到设备上并且可以为其他应用所用的数据。
应用能有许多广播接收者来响应任何它认为重要的通告。所有的接收者继承BroadcastReceiver基类。
广播接收者不能显示用户界面,然而,作为响应它们收到的信息它可以开启一个activity ,或者它门可以用NotificationManage来提醒用户。通知能获得用户的注意通过不同的方式:闪烁背景灯光,振动设备,播放音乐等。他们典型的放置一个持久图片在状态栏,同时用户可以打开它获得信息。?
内容提供商
内容提供商把对于其他应用可用的数据做一个特殊的设定。这些数据可以被存储在文件系统中,或者轻量级数据库中,或者其他任何合理的方式。内容提供商继承ContentProvider基类并实现一系列标准函数。这些函数提供其他应用来接收和存储他所控制的这种类型数据的权利。然而,应用不能直接调用这些函数。相反只能用它们ContentResolver对象和调用这个对象的函数来替代调用ContentProvider的函数。一个内容解析器能和任何内容提供商对话。它配合提供商来管理任何进程间的对话。
参考ContentProviders文件获得更多的信息关于内容提供商的

无论什么时候一个请求都应该被某个组件处理。Android确保这些组件的应用进程运行、开始如果需要的话。确保组件的一个恰当的实例可用、或创建这个实例如果需要的话。

激活组件:intents

当从内容解析器传来请求时内容提供商会被激活。另外的三种组件-activities,服务,和广播接收器会被叫做intents的异步消息激活。一个intent是一个带着信息内容的intent 对象。对activities 和 服务来说,他们命名被请求的动作、指定有效的数据路径。例如,它可以为一个给用户展示图片或者或者让用户编辑一些文本的activity 传输一个请求。对于广播接收器来说,这个Intent 对象命名被通告的动作。例如它可以告知当前人照相机按钮按下的动作。

每个组件有不同的激活方法:

  • 通过Intent?对象 Context.startActivity() or Activity.startActivityForResult()来加载(或做一些新的任务).
  • 响应activity 能通过调用它的getIntent()函数看见让他加载的最初的intent。Android调用的onNewIntent()方法Android 调用onNewIntent()来传递随后的activity?.

    一个activity 经常启动下一activity 。如果它希望从它启动的activity得到反馈,它要调用activitystartActivityForResult() 取代调用 startActivity()。例如如果它启动一个让用户挑选照片的activity ,它可以得到选择的照片。这个结果会被返回在一个被传递到activity的 onActivityResult()方法的Intent对象。

  • ?一个服务被启动(或者通过正在运行的服务给出了一个新的指令)通过一个传递到Context.startService()的Intent对象。Android调用服务的onStart()方法并且传递Intent对象。 同样的一个Intent能被传递到Context.bingdService()来建立一个持续的链接在调用组件和目标服务之间。这个服务通过调用 onBind()方法接收Intent对象人(如果这个服务还没有运行, bindService()能随意的启动它 )。例如一个activity可以和前面提到的音乐播放服务建立一个连接,以便它能通过用户界面提供用户控制播放的方法。activity会调用 bindService() 来建立连接,调用通过服务定义好的方法来影响播放。

  • ?接下来的一个章节,远程过程调用,有关于绑定服务的更多细节。

  • 一个应用可以通过 Context.sendBroadcast(), Context.sendOrderedBroadcast(), and Context.sendStickyBroadcast() 方法中的任何一个传递一个Intent对象来初始化一个广播。Android传递Intent给所有有兴趣的广播接收者通过调用它们的onReceive()方法。

    ?

了解更多关于intent的信息,可以看Intents and Intent Filters章节。

关闭组件

一个内容提供者是激活状态,只有当他响应内容解析器请求的时候。一个广播接收器是激活状态,只有当它响应广播信息的时候。所以不需要明确的关闭这些组件。

Activities另一方面提供用户界面。他们在一个长期运行的和用户的会话中可以保持激活状态,主要会话还链接,甚至是空闲的时候也可以保持连接。

同样的,服务可以持续长时间运行。所以Android有方法用来关闭服务和activitis,通过下面列出来的方式:

  • 一个activity可以被关闭通过调用它的 finish()方法。一个activity可以关闭其他activity (这个activity是它通过 startActivityForResult()方法启动的activity)?通过调用finishActivity()方法.
  • 一个服务可以被停止通过调用它的stopSelf() 方法,或者调用 Context.stopService().

组件可以通过系统被关闭当他们不再被使用或者当Andorid为其他活动的组件必须回收内存是。接下来的章节Component Lifecycles, 详细讨论了这种可能性及其后果.

描述文件The manifest file

在Android可以启动一个应用组件之前,它必须知晓这个组件的存在。因此应用程在他们打包到Andorid中的包清单文件中声明他们的组件?,.apk文件也包括了应用程序的代码,文件,资源。

这个清单是一个xml文件的格式,并且它总是被所有的应用程序命名为AndroidManifest.xml。出了声明应用的组件他做许多的事情,例如命名任何应用程序需要连接的(除了Andorid默认的库)库并且声明任何应用可以被授予的许可。

但是清单文件的主要任务是告知Android应用程序的组件。例如一个activity 可以像下面那样声明:

?

<?xml version="1.0" encoding="utf-8"?><manifest . . . >    <application . . . >        <activity android:name="com.example.project.FreneticActivity"                  android:icon="@drawable/small_pic.png"                  android:label="@string/freneticLabel"                   . . .  >        </activity>        . . .    </application></manifest>

?<activity>元素的name属性用来命名 Activity对象的子类。 iconlabel属性指向包括icon和label资源文件。icon和label能被显示给用户用来描绘activity。?

其他组件用同样的方法来声明, <service>元素是为服务组件的。 <receiver>元素是为广播接收器组件的。<provider>组件是为内容提供商组件的。Activities,服务和内容提供商不声明在清单中就不会被系统看见到它用晕都不会运行。然而,广播接收者既能被定义在清单中也可以通过代码动态的来创建(像 BroadcastReceiver对象),并且通过调用Context.registerReceiver()在系统中注册。

获得更多的怎么组织一个清单文件为你的应用程序,见The AndroidManifest.xml File。

Intent过滤器 Intent filters

一个Intent对象能明确的命名一个目标组件,如果它存在,Android找到组件(基于清单文件的声明)并激活它。但是如果一个目标不能明确的被命名,Android必须指定最佳的组件来响应这个intent。它通过比较Intent对象和潜在目标的Intent过滤器来响应intent。一个组件的intent过滤器通知Android组件可以处理的各种各样的intent。像其他必不可少的关于组件的信息,他们被声明在清单文件中。这有一个前面例子的扩展,追加了两个intent过滤器为activity:

?

<?xml version="1.0" encoding="utf-8"?><manifest . . . >    <application . . . >        <activity android:name="com.example.project.FreneticActivity"                  android:icon="@drawable/small_pic.png"                  android:label="@string/zhangyipeng"                   . . .  >            <intent-filter . . . >                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>            <intent-filter . . . >                <action android:name="com.example.project.BOUNCE" />                <data android:mimeType="image/jpeg" />                <category android:name="android.intent.category.DEFAULT" />            </intent-filter>        </activity>        . . .    </application></manifest>

在例子中的第一个过滤器- 动作"android.intent.action.MAIN"和种类"android.intent.category.LAUNCHER"的组合-是一个常见的过滤器。它使得activity作为一个应该被表示在应用平台上的用户能加载到他们的设备上屏幕列表的应用程序,或句话说,这个activity是程序的入口,当用户在平台中选择程序时他们可以看到最开始的东西。

第二个过滤器声明了acitivity能执行一个特定类型数据的动作。

一个组件能有许多intent过滤器,每个过滤器声明不同的职责。如果没有任何一个过滤器,他只能通过明确命名的组件作为目标的方式来激活。

对一个广播接收器来说它可以用代码来创建和注册,intent过滤器被直接实例化做为一个IntentFilter 对象。所有的其他的过滤器建立在清单文件中。

获得过多的intent过滤器的信息,请参见Intents and Intent Filters章节。

Activities 和任务:Activities and Tasks

正如面前提到的,一个activity能启动另一个,包括在不同应用中定义的。如果,例如你想要让用户显示一个地方的街道地图。这已经有一个activity来这这件事,所以你所有的activity需要做的是把请求信息放在一个intent对象中并且把它传递给startActivity()。这个地图浏览器会显示这个地图。当用户点击返回按钮,你的activity会重新出现在屏幕上。

对于用户,它会看起来好像这个地图浏览器是同一个应用的一部分,甚至它被定义在另一个应用程序并且运行这个应用的进程。Android保持用户的体验通过保持两个activites在同一个任务中,简单的说,一个任务是把用户的体验作为一个应用。它是一组相关的,布置在堆栈中的activities。堆栈中最底部的activity开启一个任务-典型的,它是用户在应用平台中选择的activity。这个在堆栈的顶部activity是正在运行的关注的用户动作。当一个activity开启另一个,一个新的activity被压入堆栈中;这个activity就变成了运行的activity,上一个activity被保存在堆栈中。当用户按返回键的时候,当前运行的activity被弹出堆栈,上一个activity回恢复成为了当前运行的activity。

堆栈包含多个对象,所以如果一个堆栈有多个同一个Activity子类的对象打开-多个地图浏览器,例如-这个堆栈为每个实例有不同的入口。在堆栈中的Activities从来不会重新排列,只有压入和弹出。

一个任务是一个activities的堆栈,没有类或者元素在清单文件中,所以没有办法为不依赖于activities的任务设值。任务的值作为一个整体被设置在底部的activtiy。任务下一个章节将会谈论任务的affinity;affinity的值从被设置在底部的activity中读取。

在堆栈中的所有的activites作为一个单元被一起移动。整个任务(这个activity堆栈)能被借到前台或者发送到后台。假设对实例来说当前的任务有四个activites在它们的堆栈中,三个在当前运行的activity之下。用户按下home键,转到运用平台上,选择一个新的用户程序(事实上是一个新的任务)。当前的任务转到了后台,并且这个新的任务的根activity被显示。然后,过了一小会,用户又回到了用户平台上,并且又选择之前的应用程序(之前的任务)。这个有着四个activities的任务涌现出来。这时候当用户按下返回键,这个屏幕不显示用户刚刚离开的activity(之前任务的根activity)。相反,这个任务顶部的activity被移除,同一个任务的下一个的acitivty被显示。

刚刚描述的行为是任务和activity的默认行为。但是有办法修改它几乎所有的方面。activites和任务的结合,activity在任务中的行为被开始这个行为的intent中设置的阀值和在清单文件中activity的<activity>元素中设置的属性所控制。所有的请求者和响应者都有权控制什么会发生。

在这方面,这是主要的Intent阀值:

FLAG_ACTIVITY_NEW_TASK
FLAG_ACTIVITY_CLEAR_TOP
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
FLAG_ACTIVITY_SINGLE_TOP

主要的<activity> 属性:

taskAffinity
launchMode
allowTaskReparenting
clearTaskOnLaunch
alwaysRetainTaskState
finishOnTaskLaunch

接下来的章节描述这些阀值和属性,他们是怎么相互作用的,考虑什么可以控制他们使用。

Affinities和新任务

默认的在一个引用中所有的activities都有一个affinity为其他activites。属于同一个任务的优先权。然而,一个单独的affinity能被设置为每个<activity>元素属性中有taskAffinity属性的acitivity。在不同的应用中的Activities可以共享一个affinity,或者同一个应用中的activities能被分配不同的affinities。affinity产生作用在两种情况:当Intent对象加载一个包括FLAG_ACTIVITY_NEW_TASK变量的activity,当一个activity它allowTaskReparenting 属性为真的时候。

FLAG_ACTIVITY_NEW_TASK 变量

就像早期描述的那样,一个新的activity默认的被加载到activity任务中通过调用startActivity()。它被压入相同的堆栈当被调用。然而,如果Intent对象传入startActivity()包括FLAG_ACTIVITY_NEW_TASK flag变量。系统寻找一个不同的任务来放置新的activity。经常就像这个变量的名字那样,他是一个新的任务。然而,它不是必须的。如果已经存在的任务有相同affinity作为新的activity,这个activity被加载到任务中,如果没有,它会开启一个新的任务。

allowTaskReparenting 属性

如果一个activity有allowTaskReparenting 属性为真。它能从他开启的任务中转移到有affinity任务中,当这个任务启动时。例如假设一个activity报告已选择城市的天气情况 已定义作为旅游应用的一部分。它有相同的affinity作为另一些activities在相同的

?

从用户的角度看如果一个.apk文件包含多于一个应用,你也许会想要为相互联系的activitiesz分派不同的affinities.

加载模式

这有四种不同的加载方式可以被分配给一个<activity>元素的lunchMode属性:

标准"standard" (默认的)
单一头部"singleTop"
单一任务"singleTask"
单例"singleInstance"

这些模式的不同之处在于一下四点:

  • ?哪个任务会持有相应intent的activity.activity对于"standard" 和"singleTop" 模式, 它是任务产生的intent(并且调用startActivity())--除非这个intent对象包括FLAG_ACTIVITY_NEW_TASK变量。在这种情况下,一个不同的任务被选择作就像上一章节 Affinities and new tasks描述的那样。

    。相比之下,"singleTask"?和 "singleInstance" 模式让activities总是在任务的底部。他们定义一个任务;他们从不会被加载到另外一个任务。

  • 是否可以多实例activity. "standard" or "singleTop" activity能被多次实例化。他们能属于多个任务,并且一个任务可以有多个相同activity的实例。

    相比之下, "singleTask" and "singleInstance" activities 被限制仅仅能实例化一个。至从这些在任务底部activities,这个限制意味在任务中着这不能有多于一个实例每次在设备上。

  • 是否实例能有activities在它的任务里.? "singleInstance" activity 单独存在作为唯一的activity在任务中。如果它启动了另一个activity,这个activity会被加载进不同的任务,不管他的加载模式-像FLAG_ACTIVITY_NEW_TASK在intent里。?在所有其他方面, "singleInstance"模式等同于"singleTask".

    其他三种模式提供多个activities属于一个任务。 "singleTask" activity 将会总是在任务的底部。但是他可以启动另外的会被分派给任务的activities。 "standard" and "singleTop" activities?的实例能出现在任务的任何位置。

  • 是否一个类的新的实例会被加载来处理一个新的intent. 对来默认的 "standard" 模式,一个新的实例被创建来响应每个新的intent。每个实例处理仅仅一个intent。对于"singleTop"模式来说,一个类存在的实例被重新用来处理一个新的intent如果它驻留在目标任务的activity堆栈的最顶端。如果它不能驻留在最顶端,它就不会被重新使用。相反,一个新的实例会被创建来响应新的intent,并且被加入堆栈的顶端。

    例如,如果一个任务的activity堆栈由A,B,C,D从下到上的顺序组成。所以这个堆栈是A-B-C-D。一个新的intent为D类型的activity接收。如果D有默认的"standard"加载模式。一个新的类的实例会被加载并且这个堆栈会变成A-B-C-D-D。而且如果D的加载模式是"singleTop",这个已经存在的实例会被用来处理这个新的intent(至从它在堆栈的顶部)并且保持堆栈 A-B-C-D.

    如果,从另一方面来讲,这个到达的intent是为B类型的activity而来。一个新的B的实例会被加载无论B的模式是"standard"?还是 "singleTop" (至从B不是最顶端), 所以这个结果堆栈会变成A-B-C-D-B.

    正如上面所讲,有 "singleTask" or "singleInstance" 的activity从来不会有多于一个实例, 以至于实例会被希望处理所有新的intents。一个"singleInstance" activity总是在堆栈的最顶端(前提是在任务中它是唯一的一个acitivity),所以他总是在处理intent的位置。然而,一个 "singleTask" activity也许或也许不会有其他的activities在它上面在堆栈中。如果它有,它不会在处理intent的位置上,并且这个intent会被炮制(经管这个intent被抛弃,它的到达会引起任务弹出到它保持的前台)

当一个已存在的activity被用来处理一个新的intent,这个intent对象被传给这个activity用onNewIntent()方法。(最初的开启一个activity的intent对象能被activity通过 getIntent()函数调用)。

注意当一个新的activity实例被创建来处理一个新的intent,用户能总是按下返回键来返回到上一个状态(返回到上一个activity)。但是当一个已经存在的activity实例来处理一个新的intent,用户就不能通过按返回键来返回到在处理这个新intent之前的状态。

更多的加载模式,请看 <activity>元素的描述。

清空堆栈

如果用户离开任务很长时间,系统清除任务的所有activities除了最低端的activity。当用户重新返回到任务,就像他们已经离开任务一样,除了最初的activity还在。这个想法是在一段时间过后,用户可能会丢弃他们之前做的事情。并且返回到任务中开启一些新的东西。

这是默认的。这有一些activity属性能被用来控制和修改这些行为:

alwaysRetainTaskState 属性
如果在任务最底部的acitvity属性被设置成真,这个默认的行为仅仅描述而是不能发生。这个任务保持所有行为在他们的堆栈中甚至经过很长一段时间以后也这样。
clearTaskOnLaunch 属性
如果在任务最底部的acitvity属性被设置成真,堆栈被清除直至跟activity无论什么时候用户离开任务并返回它。在另一方面,它和alwaysRetainTaskState恰恰相反。用户总是返回到他之前的状态,甚至离开很长一段时间。
finishOnTaskLaunch 属性
clearTaskOnLaunch属性很像,但是它操作单个的activity,不是整个的任务。并且它可以导致其他的activity离开,包括跟activity。当它设置成真的时候,activity保持任务的一部分仅仅为了当前session。如果用户离开并返回到任务,它不再显示。

有其他不同的方法来把当前的activity中堆栈中移除。如果intent对象包括FLAG_ACTIVITY_CLEAR_TOP?变量,并且目标任务已经有了这种在他堆栈中处理activity类型的实例。所有在这种实例之上的activities会被清除以至于它存储在堆栈的最顶端, 并可以响应intent。如果加载模式被设计成activity是"standard",它也会被从堆栈中移除,并且新的实例将会被加载来处理到来的intent。这是因为新的实例总是被创建为新的intent,当加载模式是"standard".

FLAG_ACTIVITY_CLEAR_TOP经常FLAG_ACTIVITY_NEW_TASK一起被用到.当一起用的时候,这些变量是定位在另一个任务已经存在的activity并且把它放入可以响应intent的位置。

开始任务

当intent过滤器中 "android.intent.action.MAIN"为指定的action 并且 "android.intent.category.LAUNCHER"为指定的种类,一个activity会为了一个任务被建立作为入口点。(这有一个这种类型的例子在早期提到过的Intent Filters章节)。一个这种类型的过滤器为这个activity产生一个矢量图和标题用来在应用平台中展示。给用户一种方式来加载任务和加载任务后返回。

这第二种能力是重要的:用户能离开这个任务并且可以返回这个任务。因为这个,两个加载模式让activities总是开始一个任务,"singleTask"?和 "singleInstance",应该被用仅当activity有 MAINLAUNCHER 过滤器的时候。假设,例如,什么会发生如果忘记了过滤器:一个intent加载一个"singleTask" activity,开始一个新的任务,并且用户花费一些时间在这个任务上工作。用然后按下返回键,这个任务就会隐藏在主屏幕的后面,因为它不重新出现在应用平台上,所有用户没有办法返回它。

一个相似的难题 FLAG_ACTIVITY_NEW_TASK 变量。如果这个变量产生activity来开始一个新的任务并且用户按HOME键离开它,这必须为用户有一些方法重新返回。一些入口(入通知管理器)总是开启activities在外部的任务,从来不作为他们自己的一部分,所以他们总是把intent设置成FLAG_ACTIVITY_NEW_TASK 传给startActivity()。如果你有一个activity能被调用作为一个外部的实例就可以用这个变量。注意用户有独立的方式来返回开启的任务。

在一些情况你不想让用户能返回到activity,设置<activity> 元素的finishOnTaskLaunch 为真,看早期的清空堆栈。

?

  相关解决方案