退出应用程序会感到皱眉吗?


1150

继续尝试学习Android,我读了以下内容

问题:除非我们放入菜单选项将其杀死,否则用户是否可以选择终止该应用程序?如果不存在这样的选项,那么用户如何终止应用程序?

答案:(Roman Guy):用户没有,系统会自动处理。这就是活动生命周期(尤其是onPause / onStop / onDestroy)的用途。无论您做什么,都不要放置“退出”或“退出”应用程序按钮。它对Android的应用程序模型没有用。这也与核心应用程序的工作方式相反。

呵呵,我在Android世界中迈出的每一步都会遇到某种问题=(

显然,您无法在Android中退出应用程序(但是Android系统可以在需要时完全销毁您的应用程序)。那是怎么回事?我开始认为,不可能编写一个可用作“普通应用程序”的应用程序-用户可以在决定退出应用程序时退出该应用程序。那不是应该依靠操作系统来做的事情。

我尝试创建的应用程序不是适用于Android Market的应用程序。它不是公众“广泛使用”的应用程序,而是将在非常狭窄的业务领域中使用的商业应用程序。

实际上,我真的很期待开发Android平台,因为它解决了Windows Mobile和.NET中存在的许多问题。但是,上周对我来说是个休假……我希望我不必放弃Android,但现在看起来还不太好=(

我有办法真正退出该应用程序吗?

Answers:


1285

这最终将解决您的问题,但是我首先想解决您在撰写本文时已经给出的各种答案的各种评论中提出的一些问题。我无意改变您的想法-相反,这些是供将来阅读此帖子的其他人使用的。

关键是我不能允许Android确定何时终止我的应用程序。那必须是用户的选择。

数以百万计的人对环境根据需要关闭应用程序的模型感到非常满意。这些用户根本不考虑“终止” Android应用程序,只考虑他们不打算“终止”网页或“终止”恒温器。

iPhone用户的使用方式大致相同,因为按下iPhone按钮并不一定像终止该应用程序那样“感觉”,因为许多iPhone应用程序在用户离开的地方接管,即使该应用程序确实关闭了(因为仅iPhone)目前一次允许一个第三方应用)。

就像我上面说的,我的应用程序中发生了很多事情(将数据推送到设备上,列出了始终应该存在的任务,等等)。

我不知道“列出应该始终存在的任务”是什么意思,但是“将数据推送到设备上”是一种令人愉快的小说,无论如何都不应该由活动来完成。使用预定任务(通过AlarmManager)来更新您的数据,以实现最大的可靠性。

我们的用户登录后不能每次都接到电话就这样做,而Android决定终止该应用程序。

有很多iPhone和Android应用程序都可以解决这个问题。通常是因为它们保留登录凭据,而不是强迫用户每次手动登录。

例如,我们要在退出应用程序时检查更新

在任何操作系统上,这都是一个错误。据您所知,您的应用程序“退出”的原因是因为操作系统正在关闭,然后您的更新过程中途会失败。通常,这不是一件好事。要么在启动时检查更新,要么完全异步地检查更新(例如,通过计划的任务),而从不退出。

一些评论表明,单击“后退”按钮根本不会杀死该应用程序(请参阅上面我的问题的链接)。

按下“返回”按钮不会“杀死应用程序”。当用户按下“返回”按钮时,它将完成屏幕上的活动。

仅当用户想要终止它时才终止它-决不能以其他方式终止。如果您无法编写与Android一样的应用程序,那么我认为Android不能用于编写真实的应用程序=(

然后,Web应用程序也不能。或WebOS,如果我正确理解了他们的模型(还没有机会玩过)。在所有这些情况下,用户都不会“终止”任何东西-他们只是离开。iPhone有点不同,它目前仅允许一次运行一次(有一些例外情况),因此离开的行为意味着该应用程序将立即终止。

我有办法真正退出该应用程序吗?

正如其他人告诉您的那样,用户(通过BACK)或您的代码(通过finish())可以关闭您当前正在运行的活动。用户通常不需要其他任何东西,对于编写正确的应用程序,只需要使用“退出”选项即可使用Web应用程序。


根据定义,没有两个应用程序环境是相同的。这意味着您可以看到随着新环境的出现和其他环境被掩埋而引起的环境趋势。

例如,试图消除“文件”概念的运动正在发展。大多数Web应用程序都不强迫用户考虑文件。iPhone应用程序通常不会强迫用户考虑文件。Android应用程序通常不会强迫用户考虑文件。等等。

类似地,试图消除“终止”应用程序的想法的运动也越来越多。大多数Web应用程序并不强迫用户注销,而是在一段时间不活动之后隐式注销用户。与Android相同,在较小程度上与iPhone(可能还有WebOS)相同。

这就需要更加强调应用程序设计,关注业务目标,而不是坚持与先前的应用程序环境绑定的实现模型。缺乏时间或意愿去做的开发人员会因新环境破坏了他们现有的思维模式而感到沮丧。这不是这两种环境的错,更不是因为山峰绕过而不是通过风暴而造成的故障。

例如,某些开发环境(例如Hypercard和Smalltalk)将应用程序和开发工具混合在一个设置中。这个概念没赶上了,到应用程序语言扩展的外部(例如,VBAExcel中Lisp语言在AutoCAD)。因此,想出了心理模型的开发人员以为应用程序本身已存在开发工具,因此他们要么必须更改其模型,要么将自己限制在能够满足其模型要求的环境中。

因此,当您编写:

与我发现的其他混乱情况一样,我认为开发针对Android的应用程序不会发生。

目前看来,这对您来说是最好的。同样,我建议您不要尝试将应用程序移植到Web上,因为您在Android应用程序中发现的一些相同问题也将在Web应用程序中发现(例如,没有“终止”)。相反,或者相反,有一天,如果您确实将应用程序移植到Web上,则可能会发现Web应用程序的流程可能更适合Android,并且您可以在那时重新访问Android端口。


21
一个想法浮现在脑海:如果我只是将整个应用程序重写为服务,然后将该服务视为实际应用程序-也许这样做会更好?然后,我可以“虚构”活动(就像Android希望的那样),以仅显示服务中包含的数据。在那种情况下,我也许可以保留登录状态和其他内容。使用startForeground(int,Notification)我几乎可以阻止Android终止服务...?
泰德(Ted)2010年

66
“请注意,我的用户是专业人士,使用设备的唯一目的是使用我试图移植到Android的应用程序。” 实际上,您已经指出了另外的意思(“每次听到电话都想这样做” –“电话”不是您的应用)。此外,除非您构建自己的设备,否则您不能阻止人们安装其他应用程序(如果他们愿意的话)。
CommonsWare 2010年

25
@SomeCallMeTim:不,那不是使用的正确理由killProcess()。编写更好的iOS代码是有道理的。
CommonsWare,2010年

24
@CommonsWare:对不起,但这是一个过时的回答,对我没有用。我正在移植已付款给我的代码。我应该花两倍的时间做端口,重写他们的代码,还是以降低雇主成本,让他们更快地在Android上投放更多游戏的方式来完成它?无论如何,这完全是一个学术问题:他们不希望我对引擎进行如此重大的更改,因为我无法在iOS上测试这些更改。而且这是完全错误的:对于适当的对象使用Singleton模式没有什么“坏”之处。Android只是坏了的WRT NDK应用。
2010年

10
@Ted用于更可靠的重新初始化,也许您可​​以最小化活动或服务本身存储的状态数量。取而代之的是,将大多数状态和代码放在单独的类中,该类在每次“活动”或“服务”启动时“从头开始”重新创建。
Qwertie 2012年

289

我只想在此为该线程的未来读者添加一个更正。这个特殊的细微差别使我无法理解很长时间,因此,我想确保你们没有一个犯同样的错误:

System.exit()如果堆栈上有多个活动,则不会终止您的应用程序。 实际发生的情况是该进程被终止,并立即以较少的堆栈活动重新启动。当您的应用程序被“强制关闭”对话框杀死时,甚至当您尝试从DDMS杀死进程时,也会发生这种情况。据我所知,这是一个完全没有记载的事实。

简短的答案是,如果要退出应用程序,则必须跟踪堆栈中的所有活动,并finish()在用户想要退出时跟踪所有活动(不,没有办法遍历Activity堆栈) ,因此您必须自己管理所有这些)。即使这实际上并没有杀死您可能拥有的过程或任何悬挂的引用。它只是完成了活动。另外,我不确定是否Process.killProcess(Process.myPid())效果更好;我还没有测试。

另一方面,如果可以将活动保留在堆栈中,则可以使用另一种方法使事情变得超级简单:Activity.moveTaskToBack(true)将背景简单化并显示主屏幕。

长答案包括对这种行为背后的哲学的解释。该哲学是基于许多假设而产生的:

  1. 首先,仅当您的应用程序位于前台时才会发生这种情况。如果它在后台,则该过程将终止。但是,如果它在前台,则OS会假定用户想继续做他/她正在做的事情。(如果要尝试从DDMS中终止该进程,则应先单击“主页”按钮,然后再终止它)
  2. 它还假定每个活动都独立于所有其他活动。这通常是正确的,例如,在您的应用启动浏览器活动的情况下,该活动是完全独立的,不是您编写的。浏览器活动可能会或可能不会在同一任务上创建,具体取决于其清单属性。
  3. 它假定您的每项活动都是完全自力更生的,并且可以立即将其杀死/恢复。(我不喜欢这个特殊的假设,因为我的应用程序有很多活动依赖大量的缓存数据,而这些数据太大,无法在期间高效地进行序列化onSaveInstanceState,但是这样做可以吗?)对于大多数编写良好的Android应用程序,这应该是正确的,因为您永远不知道您的应用何时在后台被杀死。
  4. 最终的因素并不仅仅是一个假设,而是操作系统的局限性: 显式杀死应用程序与崩溃应用程序相同,也与Android杀死应用程序以回收内存相同。 这最终以我们的妙招达到顶峰:由于Android无法确定应用程序是否退出,崩溃或在后台被杀死,因此它假定用户想要返回他们上次退出的位置,因此ActivityManager重新启动该过程。

当您考虑时,这适合该平台。首先,当进程在后台被杀死并且用户返回该进程时,这正是发生的情况,因此需要在中断处重新启动它。其次,当应用程序崩溃并显示可怕的“强制关闭”对话框时,会发生这种情况。

假设我希望我的用户能够拍照并上传照片。我从我的活动中启动“相机活动”,并要求其返回图像。相机被推到我当前任务的顶部(而不是在自己的任务中创建)。如果相机出现错误并崩溃,是否应该导致整个应用崩溃?从用户的角度来看,只有“相机”发生故障,应该将其返回到先前的活动。因此,它将使用堆栈中所有相同的活动(不包括Camera)重新启动该过程。由于您的活动应该经过精心设计,以便可以一口气将其杀死并恢复,因此这不成问题。不幸的是,并非所有的应用程序可以这样设计的,所以它无论罗曼·盖伊(Romain Guy)或其他人告诉您什么,对我们许多人来说都是一个问题。因此,我们需要使用解决方法。

因此,我的总结建议:

  • 不要试图杀死这个过程。调用finish()所有活动或致电moveTaskToBack(true)
  • 如果您的进程崩溃或被杀死,并且像我一样,如果您需要内存中现在丢失的数据,则需要返回到根活动。为此,您应该startActivity()使用包含该Intent.FLAG_ACTIVITY_CLEAR_TOP标志的Intent进行调用。
  • 如果您想从Eclipse DDMS的角度杀死应用程序,则最好不要将其置于前台,否则它将自行重启。您应该先按“主页”按钮,然后终止该过程。

8
实际上,由于我再次开始使用Android,所以我正在完成所有活动(在任何时间点只有一个活动处于活动状态),然后我调用System.exit(0);。在我的服务中-而且它也可以按我的意愿工作。我知道大多数人都说“不要那样做”,但是我的举动正是我想要的行为……
Ted

13
有时,终止进程非常有用-例如在编写使用本机代码的游戏时。终止进程意味着立即将所有分配的内存释放回系统。
苏珊(Sulthan)2012年

10
对于关心的人,Process.killProcess表现出与System.exit()完全相同的行为
PacificSky

6
从通用的AtivityBase派生所有活动。然后按住一个标志以强制关闭应用程序,在onResume中检查是否设置了强制关闭标志。如果是这样,请调用System.exit(0);。这将级联整个活动堆栈,并最终使该应用程序完全关闭。
Nar Gar

12
感谢您提供实际答案(这moveTaskToBack()是我一直在寻找的)。如此多的人只是说:“不,你曾经想退出应用程序而成为白痴。” 甚至没有考虑到某些情况下您确实想要它(例如,登录失败)。
Timmmm 2012年

179

我所有的应用程序都有退出按钮……因此,我经常得到用户的积极评价。我不在乎该平台的设计是否使应用程序不需要它们。说“不要把它们放在那里”有点荒谬。如果用户要退出...我可以为他们提供访问权限,以实现此目的。我认为它完全不会降低Android的运行方式,这似乎是个好习惯。我了解生命周期...并且我观察到Android在处理它方面做得不好....这是一个基本事实。


15
+1,因为不幸的是,它在目前还不能很好地完成工作(但我仍然想尝试按设计的方式工作,因此使我陷入了混乱)
理查德·勒·

25
您使用什么机制退出?
加里·鲁道夫

4
@Igor finish()-活动不会杀死应用程序(扩展应用程序)。因此,即使没有活动处于活动状态,设置仍处于活动状态且是实际的,因此当活动尝试访问它们时,它们将是以前使用的设置。System.exit(0); 另一方面会杀死该应用程序,以便在再次启动时该应用程序必须重新初始化设置。这就是手动更新应用程序时需要的,因为我经常更改数据格式,并且需要立即重新启动它们。
Nar Gar 2012年

1
好吧,这是目前完成我所需要的唯一方法。我在更新应用程序时使用system.exit(否则,我将根据代码更改获得序列化或类强制转换异常)。我应该提一下,尽管我没有给用户提供UI句柄以通过system.exit杀死该应用程序-它作为我的应用程序工程师而保留,仅在绝对需要完全卸载该应用程序时使用。其余时间使用简单的finish()(或默认的后退按钮操作)。
Nar Gar 2012年

13
是的..用“非android标准”到地狱..安卓功能强大,因为它使人们能够进行实验。我无法消化所有这些“哲学上的”答案。您使应用程序牢记您的用户。如果他们是幸福的,或者如果他们想看到这个功能,那么它绝对是罚款来实现,即使那些所谓的哲学家都反对它..
拉胡尔

144

停止将您的应用程序视为整体应用程序。这是一组UI屏幕,用户可以与您的“应用程序”以及通过Android服务提供的“功能”进行交互。

不知道您的神秘应用程序的“用途”并不是很重要。假设它通过隧道进入一些超级安全的公司Intranet,执行一些监视或交互,并保持登录状态,直到用户“退出应用程序”为止。由于您的IT部门负责命令,因此用户必须非常注意何时进入或退出Intranet。因此,您的思维定式对于用户“退出”很重要。

这很简单。进行一项服务,以将正在进行的通知放在通知栏中,提示“我在Intranet中,或者我正在运行”。让该服务执行您的应用程序所需的所有功能。具有绑定到该服务的活动,以允许您的用户访问与“应用程序”进行交互所需的部分UI。并有一个Android菜单->退出(或注销,或其他方式)按钮,告知服务退出,然后关闭活动本身。

出于所有意图和目的,这正是您想要的内容。完成Android方式。查看Google Talk或Google Maps Navigation,以了解这种“退出”的可能思路。唯一的区别是,在活动中按下后退按钮可能会使UNIX进程处于等待状态,以防万一用户想要恢复您的应用程序。实际上,这与将最近访问的文件缓存在内存中的现代操作系统没有什么不同。退出Windows程序后,所需的最有可能的资源仍在内存中,由于不再需要它们,因此正在加载时等待其他资源替换。Android是一回事。

我真的没看到你的问题。


3
@Eric,您看不到问题,因为您正在逃避它。您只需利用在旧的“程序模型”上运行的另一个程序来完成“ Android模型”无法完成的工作。要查看“ Android模型”的问题,您必须想象自己没有将任务委派给Linux / Windows机器的奢望。您必须想象自己被迫只使用运行“ Android模型”的框来执行从前端到后端的所有操作。然后,您会看到“ Android模型”的局限性像天空一样清晰
Pacerier,2014年

将您的应用程序视为整体应用程序。它用Java编写,由单个JVM(Java虚拟机)进程执行。System.exit()退出JVM,并完全并完全终止所有UI屏幕和所有内容。如果程序员要设置在多个进程中运行的多个线程的麻烦是一个例外,但是默认情况下不是这样,根据Google的说法,这不应正常进行。
杰西·戈登

@JesseGordon这不是真的。System.exit()仅从堆栈中删除一个活动。JVM立即重新初始化。看到这个答案
forresthopkinsa

1
@forresthopkinsa确定,我已经在android 7.0上对其进行了测试。一个简单的单线程应用程序仍在其自己的专用JVM实例中运行,并以该应用程序唯一的用户ID身份运行。我尚未为此测试尝试多线程应用程序。而且System.exit()仍然会杀死该应用程序的整个JVM。如果从主要活动中调用System.exit(),它将退出。如果从子活动中调用System.exit(),则JVM仍然被杀死,但是android在主/第一个活动中以新的进程ID重新启动它。android.os.Process.killProcess(android.os.Process.myPid()); 和杀死<pid>的工作方式相同。
Jesse Gordon

1
有趣的..在您链接的答案上,@ forresthopkinsa,看起来Android就像网络浏览器一样,在system.exit之后恢复活动,因此用户不会注意到它已退出,但排除了导致退出的活动。 。?奇怪的。但是无论如何,System.exit() 关闭所有活动,并释放free()的内存,并终止该应用程序的JVM。但我不知道Android会采取哪种滑稽动作来重新启动/还原它。是否要阻止应用杀手级应用?因此,我想如果有人想要退出按钮,他们应该将其放在主要活动中。
Jesse Gordon

71

这是一个有趣而有见地的讨论,许多专家参与其中。我觉得这篇文章应该从Android开发主网站中环回,因为它确实围绕Android OS的核心设计之一展开。

我还要在这里加两分钱。

到目前为止,Android处理生命周期事件的方式给我留下了深刻的印象,它将类似Web体验的概念引入了本机应用程序。

话虽如此,我仍然认为应该有一个Quit按钮。为什么?...不适合我或Ted或此处的任何技术专家,而仅是为了满足最终用户的需求。

虽然我不是Windows的忠实拥护者,但很久以前,他们引入了一个概念,即大多数最终用户都习惯了(X按钮)...“我想在需要时退出运行小部件”。

这并不意味着某人(操作系统,开发人员?)将自行决定处理此事……只是表示“我习惯使用的Red X按钮在哪里”。我的动作应该类似于“按下按钮结束通话”,“通过按下按钮关闭设备”等等,依此类推……这是一种感知。本身令我满意的是,我的行动确实达到了目的。

即使开发人员可以使用此处给出的建议来欺骗这种行为,但这种感觉仍然存在,即应用程序应根据最终用户的要求通过独立,受信任的中立来源(OS)完全停止运行(现在)。


2
对。好的Windows Mobile提供了与Windows PC相同的X按钮,只是它实际上并没有退出应用程序,只是“智能地最小化”了它。许多用户可能从未发现该应用程序并未真正退出。(该方法效果很好,尽管如果您使用.NET Compact Framework,则不会通知应用程序已发生这种情况,因此无法选择释放资源或实际退出。)
Qwertie 2012年

3
确实,这等于是在欺骗用户,让他们感到温暖,模糊。最终,最好让过去的遗物掉到一边,以免它们继续成为技术的永久固定物。移动和网络是新平台,它们的行为与台式机不同。至少,有趣的是,Android的生命周期决策似乎正在吸引用户:随着我最大的应用度过了2周年纪念日,我注意到最终用户对“退出”按钮的需求逐渐枯竭,因为他们习惯了新平台。
乔恩·奥

2
@Jon您有什么建议?没有在应用程序中的任何地方提供“退出”选项吗?
IgorGanapolsky 2012年

好吧,当用户请求退出按钮时,我会向他们精确解释与台式机不同的工作方式(这与我提到任务杀手时给他们的解释相同)。现在,信息似乎流行起来了,我不再收到这些请求。因此,我建议您解释几次(也许会给出罐头答复),然后省略按钮。或放入伪造的退出按钮,这会弹出一个对话框,解释为什么不再有退出按钮。:D(在Android 4以上版本中,用户也可以在多任务显示器的“关闭”位置滑动应用程序以“杀死”它)
Jon O

3
我也没有找到所有建议背后的道理,即“不要终止进程”。在我看来,客户永远是对的,因此,如果需要的话,在请求后提供退出按钮并“说谎给用户以给他们一种温暖,模糊的感觉”怎么办?这部分是编写优秀应用程序的全部内容。大多数用户不了解也不关心引擎盖下的实际情况,但是如果他们喜欢您的应用程序并且它做了他们想要和期望的事情,他们会回来购买更多的应用程序。那就是我们所有人想要的,不是吗?还是我错过了什么?
DDSports 2014年

37

可以退出,或者通过按下Back按钮或调用finish()你的Activity。如果您想明确杀死它,只需finish()从a 呼叫MenuItem

Romain并不是说不可能做到这一点,只是说它没有意义-用户无需担心退出或保存他们的工作或其他事情,因为应用程序生命周期的工作方式鼓励您编写可以自动保存和保存信息的智能软件。无论发生什么情况,都可以恢复其状态。


5
它是否满足目的并不是没有意义的,而在我们的应用程序中,它就做到了。例如,我们要在退出应用程序时检查更新。我们无法退出该应用,因此无法进行任何更新。一些评论表明,单击“后退”按钮根本不会杀死该应用程序(请参阅上面我的问题的链接)。
泰德(Ted)2010年

2
正如Romain所说的,这不是核心应用程序的工作方式。因此,如果用户习惯于按“返回”来退出应用程序,那么他们似乎会继续使用您的应用程序而不是明确选择退出吗?您可以在启动时或onDestroy()上进行更新检查,或使用重复警报..似乎不需要用户触发。
Christopher Orr 2010年

1
汤姆:我已经为Windows Mobile编码了将近5年。多数民众赞成在电话与“有限的资源”。那里没有这种行为,也没有问题,它也不会以那种“老大哥”的方式行事。“真正的应用程序” =程序员可以对其进行更多控制,即退出,删除GUI-stuff等...
Ted

1
周杰伦:因为如果它仍在内存中,我将无法更新该应用程序。无法使用正在使用的delelte文件,对吗?我想在退出时进行更新,因为我们不能强迫用户在启动时进行更新。这与他们的工作方式和需求有关。由于不同的原因,他们在轮班开始时被迫进行更新是不行的。它有点复杂。
Ted 2010年

1
周杰伦:不,正如我所说的那样,它不是Market App,也不是。它是一个非常专业的应用程序,不适合一般使用。
Ted 2010年

31

这场争论归结为一个古老的问题,即开发人员是否最了解或用户是否最了解。人为因素各个领域的专业设计师每天都在为此奋斗。

Ted指出,市场上下载次数最多的应用之一是“ App Killer”。人们在退出申请时会获得一些额外的5-羟色胺。他们已经习惯了台式机/笔记本电脑。它使事情保持快速发展。它可以使处理器保持凉爽,并保持风扇无法打开。耗电量少。

当您认为移动设备是一艘小得多的船时,您会特别欣赏他们的动力“将多余的东西扔了”。现在,Android开发人员已经推理出该操作系统最了解并且退出应用程序是过时的。我全力支持。

但是,我也相信您不应该让用户感到沮丧,即使这种沮丧是出于他们自身的无知。因此,我得出的结论是,拥有“退出”选项是一个好的设计,即使它主要是一个安慰剂按钮,除了关闭视图外也无济于事。


8
是的,拥有“退出”按钮确实对用户友好。如果用户有5个活动,该如何退出该应用程序?当然,他们可以多次按下,但我认为他们不希望这样做。
IgorGanapolsky 2012年

4
只有5个?Android 2.2网络浏览器使我花了几分钟点击后退按钮,直到我最终退出
Joe Plante 2012年

3
当他们开发WORKS的内存管理器时,我将开始听听android的开发人员。从Froyo开始,它的运行效果非常差,杀死了随机应用程序,重新启动了不需要的应用程序(并且没有意向来正常启动它们的意图),以及OTOH,当内存达到50MB可用容量时,速度会减慢至完全爬网。
DVK 2012年

10
如果您的宗教信仰说Android Task Killer是“不必要的”,但是使用ATK杀死没有业务运行的愚蠢任务,则会使操作系统从正常速度的1-5%爬行回正常速度的100%(实测)在2年中,每当系统达到50MB免费低端时,在1000次ATK使用中有100%的时间,您的信仰是错误的
DVK 2012年

@JoePlante您可以先关闭所有打开的选项卡和窗口,然后只需按一次返回按钮即可退出:)至少在我的GS2上。
拉丹

29

泰德(Ted),您想完成的事情可以完成,也许只是您现在的想法不行。

我建议您阅读“活动和服务”。停止使用术语“应用程序”,并开始引用组件,即活动,服务。我认为您只需要了解有关Android平台的更多信息;与标准PC应用程序相比,这是一种观念上的变化。您的帖子中都没有一个单词“ Activity”(缺少FAQ引用,即没有您的单词)的事实,这告诉我您需要阅读更多内容。


我已经阅读了android.com =上的大多数内容,并且可以在我谈论活动的地方链接到我的几个问题,所以事实并非如此(例如:stackoverflow.com/questions/2032335/…stackoverflow.com/questions/ 2032335 /…等。。。)但是,我可能还是走了最后一步,并尝试将who“ app”创建为Servce ...
Ted

4
一个应用程序可以包含服务和活动,听起来您的应用程序可能同时需要两者。该活动仅是UI部分。
亚伦2010年

23

博客文章何时在Android Apps中包含退出按钮(提示:从不)对它的解释远比我能做到的好得多。我希望每个Android开发人员都已经阅读过。

摘录:

根据我的经验,[用户]真正想要的是: 一种明确的方法来保证应用程序将停止消耗资源(电池,CPU周期,数据传输等)。

许多用户认为退出按钮实现了此要求,并要求添加它。为了讨好他们的用户,开发人员不得不添加一个。此后不久,他们俩都失败了。

  • 在大多数情况下,退出按钮只是调用Activity.finish()。这完全等同于单击“后退”按钮。 究竟。 服务保持运行,并且轮询不断发生。用户可能会认为自己已经杀死了该应用程序,但实际上并没有杀死它们,很快他们就会更加恼火。
  • 退出行为现在不明确。您的退出按钮应该只是关闭活动,还是应该停止所有相关的服务,接收器和警报?应该Back怎么办?如果他们撞了Home怎么办?如果您的应用程序有一个小部件会怎样?退出按钮是否也应该阻止它更新?

解决方案是使后退按钮的行为与您期望退出按钮的行为相同。更好的是,只要看不见该应用程序就停止消耗资源。

继续阅读完整的文章。


3
退出和返回并非总是用于同一目的。以潘多拉(Pandora)为例。当您点击退出该应用程序时,它不会退出该应用程序(将其作为服务保留在后台播放)。
IgorGanapolsky 2012年

@IgorG。音乐播放器应用程序需要一个“停止”按钮来停止播放音乐,而不需要一个“退出”按钮来退出该应用程序。
Dheeraj Vepakomma 2012年

您是否曾经使用过Pandora,iHeartRadio,Spotify,Jango和其他音乐流媒体应用程序?他们都有退出按钮。停止音乐播放并不等同于退出应用程序。特别是如果您在通知栏中运行了一项服务。
IgorGanapolsky 2012年

2
不论是否神话,是否原始用户,但几乎在任何平台和OS上编写的几乎所有UI软件都实现了退出/关闭/退出按钮。您还将如何实施它?
IgorGanapolsky 2012年

3
@ DheerajV.S。,只要看不见应用程序就停止消耗资源?不好的建议。 非常。 非常x99。每当我尝试通过电子邮件向自己发送照片时,都必须让该应用程序保持可见状态5分钟,因为如果将其最小化,它将停止通过电子邮件发送照片。正确,我不能整整使用手机5分钟,因为某些开发人员认为应用程序仅在可见时才能运行。现在想象发送一个更大的文件,例如视频.....
Pacerier 2014年

21

答:(Roman Guy):用户没有,系统会自动处理。这就是活动生命周期(尤其是onPause / onStop / onDestroy)的用途。无论您做什么,都不要放置“退出”或“退出”应用程序按钮。它对Android的应用程序模型没有用。这也与核心应用程序的工作方式相反。

1:完全退出应用程序通常是强制性的,但这并不是没有用的。如果Windows没有退出选项怎么办?由于内存已满,并且操作系统必须猜测使用了哪些程序,因此系统运行缓慢。我不在乎Romain Guy甚至Larry Page和Sergey Brin怎么说,这些都是毫无疑问的事实:系统运行速度变慢,因为它们必须终止任务才能获得内存,然后才能启动新的应用程序。您只是无法告诉我,不需要花费时间就可以杀死应用!甚至来自遥远恒星的光需要时间......还有就是在允许用户完全关闭一些应用程序使用。

2:与核心应用程序的工作方式相反?那是什么意思?当我现在完成一个应用程序的运行时,它不再做任何工作……只是在需要内存时等待被操作系统杀死。

总而言之,最小化和退出之间有明显的区别,并且两者都不会碰到对方。我们是否在每个螺丝钉中都留下了螺丝刀?还是每扇门的钥匙?我们是否将所有设备都保持高位,直到断路器烧断并且需要打开另一台设备?我们是否在洗碗机中放满了餐具,每次只拿出足够的空间来腾出一些新的脏东西?我们是否让所有汽车都在车道上行驶,直到-哦,没关系。

如果用户想最小化一个应用程序,那么最好的办法就是最小化它。如果用户要退出应用程序,则最好退出。

皱眉吗?这是Android的观点-他们对此并不满意。许多独立的新秀Android开发人员对此并不满意。

但是,当涉及到它时,就会出现好的编码和不好的编码。有好的程序流程模型,有好的程序流程模型。

当用户知道它们已经完成时,将程序留在内存中并不是很好的程序流程。它绝对没有任何用处,并且在启动新应用程序或运行应用程序分配更多内存时会减慢速度。

这有点像您的汽车:有时候您会使其保持运行状态,例如在停车灯处停车,或者快餐店驶过,或者在ATM上停车。但是在其他情况下,您确实希望将其关闭-例如上班,杂货店甚至是家中。

同样,如果您正在玩游戏并且手机响了,可以。暂停游戏并使其继续运行。但是,如果用户在一段时间内完成游戏,那么一定要让他们退出。

某些应用程序上的退出按钮应该比其他应用程序更靠前。例如,游戏或用户可能想要完全退出的程序应该具有明显的退出。其他程序,例如电子邮件程序,希望退出是不太可能的(这样它就可以继续检查电子邮件)-这些程序不应通过退出选项浪费主控制输入屏幕空间,但是为了获得良好的程序流程,应该有一个退出选项。如果某人决定在覆盖范围较差,或者在Skype通话中或其他情况下不希望自己的邮件程序尝试检查电子邮件怎么办?如果他们愿意,让他们退出电子邮件程序!

暂停和退出是两项至关重要的任务,两者都不能发挥另一个作用。


2
“如果用户想要最小化一个应用程序,那么最好的办法就是最小化它。如果用户想要退出一个应用程序,那么最好退出。” -有件事(基于十多年的经验):用户很少知道他们想要什么。如果您不帮助他们,则必须进行更改。关于上面的示例:让我给您其他示例:您正在汽车上工作,并准备了一张桌子。您是否总是收拾好所有必要的工具放在橱柜中,或将最常用的工具放在手边?只是放下一个大的已用过的旧玩具来放置新的玩具?
HoGo

4
HoGo,谢谢您的评论。当然,我不同意。具体来说,据我所知,您的观点是,由于某些用户不知道应该做什么,因此,不要让任何用户去做他们应该做的事情,甚至不要让知道他们应该做的事情的用户也可以。如果android有一种方法可以准确地知道是否应终止应用程序而不是将其最小化,则可以。但是事实并非如此,强迫所有用户退出时总是处于最小化状态会导致设备性能下降。
杰西·戈登

问题是,系统知道,当您启动一个应用程序并且没有内存时,它应该杀死最后一个应用程序。用户不应该知道这一点。您只想要它,是因为您是一个人类,就像被控制的砍伐,愚蠢的肌肉记忆,甚至毫无意义的控制一样,不得不关闭程序。发明了计算机来实现自动化,我希望Windows能够像Android一样工作,并且对我来说会自动关闭,但是我必须记住保存并退出,这很愚蠢,用户为什么要这样做?计算机应该管理它们的内存,我还有其他事情要管理。
Luiz Felipe

实际上,我没有关闭Windows计算机中的程序,而是拥有32GB的RAM,只是让所有程序保持运行状态,当我完成工作时就关闭它们。为什么要关闭程序,然后在5分钟后再次打开它,这没有任何意义。考虑一个需要2分钟才能响应的大型C ++项目,我只是将Visual Studio永久打开。而且我希望它在打开15天后也不会崩溃(是的,我为此使用ECC内存)。
Luiz Felipe

与机器车间的比喻是一个很好的例子,我也把最常用的工具放在桌子上,我不选择工具,也不用每次都放回去。另外,我不会开始新的一天,打开电脑,等待它启动,打开IDE,等等。我只是让它继续运行,现代计算机可以在40w下闲置,为什么要关闭?它也减少了零件的磨损(无浪涌电流,EEs知道:))
Luiz Felipe

19

我认为关键是除非您拥有越野车软件,否则无需退出该应用程序。当用户不使用应用程序且设备需要更多内存时,Android会退出该应用程序。如果您有一个需要在后台运行服务的应用程序,则可能需要一种关闭服务的方法。

例如,当应用不可见时,Google Listen会继续播放播客。但是总是有暂停按钮可以在用户使用完播客后将其关闭。如果我没记错的话,“听”甚至会在通知栏中添加快捷方式,以便您始终可以快速进入暂停按钮。另一个示例是例如Twitter应用程序之类的应用程序,该应用程序不断轮询Internet上的服务。这些类型的应用程序确实应该允许用户选择轮询服务器的频率,或者甚至选择在后台线程中轮询。

如果需要让代码在退出时运行,则可以根据需要重写onPause(),onStop()或onDestroy()。 http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle


5
与我发现的其他混乱情况一样,我认为开发针对Android的应用程序不会发生。这是太多的“老大哥”之类的事情,Android告诉我应该运行或不运行哪个应用程序。我作为程序员应该有这种选择,而不是google或android =(
Ted

3
当另一个应用程序出现在顶部,或者您按退回之类的按钮时,活动(活动的用户界面)就会消失。用户没有与他们进行交互,因此保存状态最安全,以防用户长时间不回来,依此类推。没有什么可以阻止您编写代码Service来保持正在进行的工作在后台进行的,例如接收数据推送或其他内容。当您使用其他应用程序时,Google Talk不会停止工作。与音乐播放器相同。查看那里的其他应用程序以及它们如何工作。
Christopher Orr 2010年

3
您应该能够保存凭据,这样用户就不必在每次接到电话或离开您的应用程序时都登录。我建议您查看Android的生命周期。当应用程序暂停,停止或销毁时,您可以保存所有相关数据,因此当应用程序再次打开时,它们将保持原样。用户甚至不需要知道该应用程序曾经被停止过。
杰·阿斯克伦

1
我可以想象一个用户可能想要退出一些真正占用大量资源的应用程序。也许它应该只是在暂停时减少对资源的使用,但这并不总是可能的
Casebash 2010年

1
我提出这个问题4年后,我仍然看到这个问题仍然存在=)我确实确实在后台将其作为服务运行,但是我添加了退出按钮,因为4年后我仍然感到这是必要的和重要。而且我也看到越来越多的应用程序也具有该功能(例如Skype)。
Ted 2014年

19

如果您无法理解如何使数据/连接(从而使您的“应用程序”)持久化,那么您将无法完成Android所需的工作。

那些下载那些可爱的小App Killer的人通常会发现它们无助于电池寿命或内存使用率的提高,但是却阻碍了操作系统有效地管理内存……

http://android-developers.blogspot.com/2010/04/multitasking-android-way.html


几天前,当我们谈论任务杀手时,一篇非常有启发性的文章出现在Android reddit上。主旨在于,使用任务杀手仔细或者你可以实际上最终伤害了你的电池寿命: reddit.com/r/Android/comments/cwhm6/...
尼尔Traft

@Neil Traft,我发现帖子中的评论很有启发性。商店的销售代表正在为其客户推荐并安装杀手
ers

3
@Dan,我怎么可能完全退出一个已经用完一周的应用程序而阻碍Android OS正常工作呢?因此,有更多的可用内存。那不可能阻止android!不过,它肯定可以在以后加快速度!如果我知道我已经用了一段时间了,那么它绝对没有用。它只会占用内存,迟早我会启动一个新应用,而操作系统将有一个额外的延迟,因为它必须杀死一些我以前已经了解过的应用程序。
杰西·戈登

@Jesse Gordon,杀了一个应用程序之后,您是否看过实际过程?它们重新启动,操作系统认为有问题...操作系统将在需要内存时终止应用程序。您甚至没有阅读此处提到的文章中张贴的内容?
2013年

@Dan,想想Android会做这样的事情。。。它确实需要进行认真的洗白教育。
Pacerier,2014年

18

我会考虑阅读Addison-Wesley出版的“ Android无线应用程序开发”。我刚刚完成它,它非常彻底。

您似乎对Android平台有一些基本的误解。起初,我对Android应用程序的应用程序生命周期也感到有些沮丧,但是在加深了解之后,我开始真正享受这种方法。这本书将回答您所有的问题,甚至更多。对于新的Android开发人员来说,这确实是最好的资源。

另外,我认为您需要放弃现有应用程序的逐行端口。为了将您的应用程序移植到Android平台,一些应用程序设计将有所更改。由于移动设备相对于台式机系统而言资源非常有限,并且允许Android设备以有序且资源感知的方式运行多个应用程序,因此必须使用应用程序生命周期。对平台进行更深入的研究,我想您将意识到您想要做的事情是完全可行的。祝你好运。

顺便说一句,我绝不隶属于Addison-Wesley或与此书相关的任何个人或组织。重新阅读我的帖子后,我觉得自己有点狂热。我真的非常非常喜欢它,并发现它非常有用。:)


2
谢谢你的书提示。如果可以并且我决定使用Android端口,我将对其进行研究。不过,请再次声明:在计算机方面,我们的用户不是最新的。我将很难让他们使用例如Android中的NotificationBar。太小(他们的手指很大)。对于他们来说,这是一个不同的世界,因此我们需要保持简单,并为用户提供选择。我们牢记这一点构建了.NET解决方案-不要给他们一个选择=)
Ted 2010年

我听到了。您必须假设大多数用户不是很聪明。
安迪

8
我已经厌倦了移动设备拥有的“资源”很少的口头禅。唤醒后,它们将以500Mhz以上的速度运行,并具有大量的内存。我以前的Dell Axim有128MB的RAM。当前的设备通常超过512RAM,并在1GHZ上运行!那是我以前的Pentium 90Mhz的10倍,而且我没有听到有人说“资源非常有限”。是时候醒来闻起来咖啡的味道了-我们现在是2010年,而不是80年代。
泰德(Ted)2010年

16

几乎99%的时间都不需要Android应用程序接管其自身的生命周期。在大多数情况下,它取决于更好的计划或更智能的应用程序设计。例如,宁可构建内部服务(未导出)来处理下载等,也可以设计围绕用户工作流的操作和任务。

话虽这么说,有志者事竟成。Android通过android.os.Process类提供了比Java更好的API,用于控制基础流程。而且与Java不同,它不会将开发人员全部隐藏在简单的java.lang.System.exit()调用之后,因此无法像开发人员那样对待开发人员。

那么,您如何要求应用程序在Android中自杀呢?好吧,诀窍很简单:

通过继承标准android.app.Application类来创建自己的Android应用程序类(请记住在AndroidManifest.xml文件中进行声明)。

覆盖onCreate()方法,并存储启动您的应用程序的进程ID:

this.pid = android.os.Process.myPid(); // Save for later use.

现在要杀死您的应用程序,请提供kill()方法:

android.os.Process.sendSignal(pid, android.os.Process.SIGNAL_KILL);

现在,每当您需要您的应用程序自杀时,只需键入强制转换应用程序上下文,然后调用您的kill方法!

((MySuicidalApp) context.getApplicationContext()).kill()

只需记住,由于Android中的流程管理策略(特别是与服务相关的策略),Android可能只是选择重新启动服务(请参阅android上不应该使用任务杀手)。


是的,我只是来这里是因为我想在某种情况下关闭我的应用程序,我的OBB数据缓存已损坏,我需要重新启动整个应用程序
Luiz Felipe,

14

当我在Android中构思一个应用程序时,我会这样看:

  • 您正在使用您的应用程序
  • 电话响了
  • 你接电话
  • 通话结束时,您将回到原先的位置

为此,您只需要Back按键或Home电话按键(短按或长按)和通知栏。

退出应用程序时,我只会使用Back按钮,直到退出该Home按钮或按钮为止。

我认为这就是大多数应用程序的构想。但是,如果我需要某种会话或连接,则可以使用登录/注销按钮和通知(标题栏或其他任何东西)向用户表明清楚。与纯“退出”样式应用程序相比,这是一种完全不同的样式。

在PC上,您具有多GUI桌面,在Android上,您显然具有多任务,但是一次只能显示一个应用程序(我这里不考虑小部件^^)。在手机上,您可以随时收到比您正在做的事情更重要的通知。

因此,应用程序的整个概念依赖于“输入应用程序-工作-退出应用程序”不同的东西。


12

嗯...

我认为您只是没有以正确的方式看到Android应用。您可以轻松地执行几乎想要的操作:

  • 应用程序活动是否像开发人员生命周期文档中所鼓励的那样保存/还原状态。

  • 如果在还原阶段需要登录(没有可用的登录/会话信息),请执行此操作。

  • 最终添加一个按钮/菜单/超时,在这种情况下,您将finish()不保存登录名和其他会话信息就进行操作,从而隐含了应用程序会话的结束:因此,如果应用程序已启动/再次重新启动,它将启动一个新的会话。

这样一来,您就不必担心应用程序是否真的从内存中删除了。

如果你真的想从内存中删除(这是气馁,BTW目的是什么?),你可以在年底有条件杀死它onDestroy()java.lang.System.exit(0)(或可能restartPackage(..)?)。当然,仅在您要“真正结束应用程序”的情况下才执行此操作,因为这onDestroy()是活动的正常生命周期的一部分,而根本不是应用程序结束。


11

由于Android上下文中的应用程序只是一堆模糊的相关活动,因此退出应用程序并没有多大意义。您可以完成()一个活动,然后将绘制活动堆栈中上一个活动的视图。


2
在某些情况下,一定要退出应用程序才有意义。如果您每月使用几次该程序几分钟,那么完全退出该应用程序无疑具有好处。这样做的好处是,当操作系统内存不足且手机响了,并且您按下了“接听”按钮,并且等待android释放一些内存时,操作系统就不必花一周的时间退出该应用程序这样您就可以接听电话。或者,也许您收到了一封电子邮件并想阅读它-如果操作系统不首先释放它,则需要更多内存的任何应用程序都将更快地启动。
杰西·戈登

3
@JesseGordon所说的话,以及退出这个原因的另一个方面是有道理的:如果我退出此资源密集型应用程序,我知道我将不再使用一个月,则操作系统有时会错误地杀死其他一些应用程序当资源变得稀缺时,同时保持这个无用的资源消耗应用程序的运行状态……使其他应用程序恢复所需的时间比原先所需的时间长。
唐·哈奇

10

我同意泰德的看法。我知道退出应用程序不是“ Android方式”,但似乎不应该排除它。以下是您可能希望真正退出应用程序(而不仅仅是活动)的三个原因:

  1. 用户可能希望在内存不足的情况下控制哪些应用程序被杀死。如果重要的应用程序A在后台运行,那么您可能要在完成操作后退出应用程序B,以免应用程序A被操作系统杀死。

  2. 如果您的应用程序在内存中缓存了敏感数据,则您可能想杀死该应用程序,以使病毒/蠕虫/恶意应用程序无法正常运行。我知道安全模型应该可以防止这种情况,但是以防万一...

  3. 如果您的应用程序使用的资源(如网络,CPU,传感器等)可能会对电话产生不利影响,那么确保释放这些资源的一种方法是退出应用程序。我了解行为良好的应用应在不需要时释放资源。但是再次,退出应用程序似乎是确保这一点的合理方法。


6
您认为什么代表了“申请”?如果我打开Facebook应用程序并设置新的个人资料照片-我的“相机”或“图库”应用程序将启动。作为用户,我仍在执行相同的任务(使用Facebook)。如果随后我决定关闭Facebook,则我的“相机和图库”应用也必须关闭(因为它们是从Facebook启动的活动)...如果我正编辑其他一些照片而只打算关闭Facebook,该怎么办? ?您将把问题转移到潜在的数据丢失上。
seanhodges

好吧,我认为这不会造成数据丢失。如果您有一个第三方活动与您自己的活动在同一任务中运行,并且您自己的活动是带有退出按钮的活动,则用户必须先finish()进行第三方活动,然后才能点击退出按钮。并且第三方活动当时应保存所有未保存的信息。我认为您无法使用应用程序切换器返回退出按钮活动,除非该活动在单独的任务中运行。而且,如果这是一个单独的任务,那么它是一个单独的过程,因此不会被退出按钮杀死。
尼尔·特拉夫特

2
1.我认为99.99%的Android用户不应该担心操作系统如何管理幕后应用程序。其余的人是极客,他们会发现高级工具确实可以使系统按照他们想要的方式工作。2.当活动暂停或停止时,您始终可以卸载任何敏感数据。3.与上述相同,可以在生命周期回调方法中释放资源。活动恢复后,可以再次分配资源。
ZsoltTörök2010年

4
我认为相当有趣的是,许多Android用户正在安装“ Advanced Task Killer”,该应用程序会关闭其他应用程序,因为您通常无法自己关闭它。我自己一直在使用它。退出应用程序并不是我无法做到的事情。
泰德(Ted)2010年

2
@ZsoltTörök,99.99%的人使用慢速的计算机/电话,被迫放弃选择,担心操作系统如何管理幕后应用程序。
Pacerier,2014年

10

Linux内核具有一项称为“内存不足杀手”的功能(如上所述,这些策略可在用户空间级别配置,并且内核不是最佳策略,但绝不是不必要的)。

Android大量使用它:

一些用户空间应用程序可用于协助这些终止应用程序,例如:


9

您显然已经在finish()命令中找到了想要的答案。这不会将您的应用程序从内存中删除,但是Android会在需要资源时执行此操作,因此不会显着地造成任何影响。

我仅补充说一下,为了获得应用程序退出通常具有的全部效果,您希望将应用程序的状态重置为设备启动后首次运行时的正常状态。在您的所有活动上调用finish()。这样,如果用户再次选择您的应用程序,则该应用程序似乎已“全新”运行,而在模拟“退出”之前的任何位置都没有剩余任何状态。

如果有一些仅应在“退出”时发生的特殊操作,例如保存用户的工作或其他任何操作,也可以在上述例程的重新初始化部分之前执行这些操作。

通过这种方法,您可以实现拥有“退出”命令的目标,而不会违反Android的哲学,即将操作系统资源(包括应用程序的关闭)的管理权交给操作系统。

就个人而言,我不会使用这种方法,因为Android用户希望应用程序在重新访问时能够保持其连续性,因此他们不习惯于“退出”应用程序的方式。相反,我将支持“清除”功能,用户可以调用该功能将应用重置为某些默认的初始状态,而无需在过程中“保留”该功能。

一种例外情况是,用户按下后退按钮的次数足以导致应用程序关闭。在这种情况下,用户不会期望状态会被保存(如果应用程序中存在未保存的状态,那么作为开发人员,您应该具有处理后退按钮的代码,该按钮可检测到未保存的数据,并且提示用户将其保存到SharedPreferences或文件或其他非易失性介质中。

关于system.exit(0):

如果您确实决定使用system.exit(0)以粗鲁的终结性来关闭您的应用程序(例如,由于最后按下后退按钮),那么我会警告您,尽管这对我来说是“可行的”,但在某些情况下案例是我能够关闭应用程序而没有任何痕迹的唯一方法,当您使用这种方法时,在Jelly Bean中会出现一个小故障。

具体来说,如果您使用“最近使用的应用程序”列表打开应用程序,然后使用“后退”按钮关闭该应用程序(通过system.exit(0)实现该关闭操作),则“最近使用的应用程序”列表将再次变为可见从来没有被关闭过。如果您然后在该列表中您的应用程序的入口点击运行它第二次从同一已经打开,最近访问的应用列表中,将不会有响应。

我怀疑这是因为“最近使用的应用程序”列表保留了对您的应用程序的引用,该引用由于您已使用system.exit(0)关闭了该应用程序而无法运行。使用finish()更文明地关闭您的应用程序可能已经以某种方式通知操作系统,使操作系统可以刷新其“最近使用的应用程序”列表,但是system.exit(0)显然不这样做。

这本身并不是一个大问题,因为很少有人会从“最近的应用程序”中打开一个应用程序,然后退出它,然后立即从同一打开的“最近的应用程序”列表中再次打开它。如果他们点击主页按钮,然后重新打开 “最近使用的应用程序”列表,则您的应用程序条目将在那里,并且将完全起作用。 但是我认为这表明使用system.exit(0)可能会干扰您的应用程序和操作系统之间的正常通信,这表明使用此方法可能会导致其他更严重甚至更微妙的后果。


您也许可以在调用finish()之前删除最近的应用程序条目?如果时间允许,我会尝试一下。我有一个带有小型启动器活动的前台服务。由于Activity很小,因此如果不将其杀死并掩埋也没什么大不了的,但是告诉Android在可能的情况下可以先采取这项措施是有意义的。
nsandersen

9

我希望事情会随着时间而改变。如果操作系统正确地将应用程序进程沙箱化,则用户应该能够终止该应用程序或进程。有一种观念认为应用程序应该写得完美,否则用户将只使用遵循所有SDK建议的应用程序。我认为这是一个艰巨的任务。


我知道。苹果产品对某些消费者有好处。它们对开发人员不利。Android OS完全有可能成为手机的“ PC世界的Windows OS”。可能会更好。它比PC世界的窗口更开放,但它不允许我们编写任务管理器。
dipu 2010年

7

有一个(相对)简单的设计,使您可以解决“出口”难题。使您的应用具有“基本”状态(活动),这只是一个空白屏幕。在活动的第一个onCreate上,您可以启动应用程序主要功能所在的另一个活动。然后,可以通过finish()这第二个活动并返回到空白屏幕的基础来完成“退出”。操作系统可以根据需要将空白屏幕保留在内存中...

本质上,因为您不能退出OS,所以您只是转变为自己创建的虚无。


2
好主意。但是,即使完成一项活动(或服务)也不会停止操作系统。哦,不,即使执行了onDestroy之后,所有变量和内容仍然存在。我只是看到在Service中,即使onDestroy的名称也一样……
Ted

2
...因此System.exit(0)帮助了=)
Ted

7

如果没有退出功能让应用程序开发人员杀死自己的应用程序,那将是非常糟糕的设计。

我的应用程序需要允许用户在运行时动态地动态更改数据,并且用户需要重新启动我的应用程序才能产生更改效果,但Android不允许我的应用程序自行重启。Android OS的设计应用程序生命周期非常糟糕。


9
public void appRestart(){Intent i = new Intent(getBaseContext(),MyActivity.class); i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(i); }
androidworkz

2
上面的注释代码确实运行良好。至少您可以转到第一个活动,而不是完全退出App。:)
Harpreet 2012年

7

要随时关闭应用,请FLAG_ACTIVITY_CLEAR_TOP在Intent中使用标志,然后system.exit();

或有类似的方法,但是没有system.exit()退出时调用此方法:

public void exit() {
    startActivity(new Intent(this, HomeActivity.class).
    setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK).putExtra(EXIT_FLAG, true));
}

在您HomeActivity.onCreate()添加以下代码

protected void onCreate(Bundle savedInstanceState) {
    if (getIntent().getBooleanExtra(EXIT_FLAG, false)) {
        if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) == 0) {
            finish();
        }
    }
......................

这将在不中断Android生命周期的情况下起作用。


7

首先,永远不要永远不要使用System.exit(0)。就像让一个人睡觉时把他的头打了!

第二:我正面临这个问题。在分享我的解决方案之前,我想分享自己的想法。

我认为“退出按钮”很愚蠢。真的真的真的很愚​​蠢。而且我认为要求您的应用程序退出按钮的用户(消费者)也很愚蠢。他们不了解操作系统如何工作以及如何管理资源(并且做得很好)。

我认为,如果您编写了一段不错的代码,并且在正确的时间和条件下执行了正确的事情(更新,保存和推送),并且使用了正确的事情(服务和接收器),那么它将很好地工作,而且没人会抱怨。

但是,要做到这一点,您必须学习并学习如何在Android上运行。无论如何,这是我为用户提供“退出按钮”的解决方案。

我创建了一个在每个活动中始终可见的“选项菜单”(我有一个超级活动)。

当用户单击该按钮时,将发生以下情况:

Intent intent = new Intent(this, DashBoardActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

SharedPreferences settings = getSharedPreferences(getString(PREF_ID), Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean(FORCE_EXIT_APPLICATION, true);

  // Commit the edits!
editor.commit();
startActivity(intent);
finish();

因此,我将要杀死的应用程序保存在SharedPreferences中,然后启动一个Intent。请查看那些标志;这些将清除所有我称为DashBoard Activity的后台程序,这是我的“ home”活动。

因此,在“仪表板活动”中,我在onResume中运行此方法:

private void checkIfForceKill() {

    // CHECK IF I NEED TO KILL THE APP

    // Restore preferences
    SharedPreferences settings = getSharedPreferences(
            getString(MXMSettingHolder.PREF_ID), Context.MODE_PRIVATE);
    boolean forceKill = settings.getBoolean(
            MusicSinglePaneActivity.FORCE_EXIT_APPLICATION, false);

    if (forceKill) {

        //CLEAR THE FORCE_EXIT SETTINGS
        SharedPreferences.Editor editor = settings.edit();
        editor.putBoolean(FORCE_EXIT_APPLICATION, false);

        // Commit the edits!
        editor.commit();

        //HERE STOP ALL YOUR SERVICES
        finish();
    }
}

它会很好地工作。

我唯一不了解为什么会发生这种情况的原因是,当我完成最后一次完成(并且我已经检查:遵循所有正确的onPause→onStop→onDestroy流程)后,该应用程序仍在最近的活动中(但是它是空白)。

似乎最新的意图(已启动DashboardActivity)仍在系统中。

我必须挖掘更多才能将其删除。


8
没有多少消费者知道操作系统是什么,更不用说操作系统如何了,这并不会使他们变得愚蠢。想要退出/退出/关闭按钮可使它们正常。当您离开房间时,请关掉灯,更重要的是,当您离开房屋时,请锁上门,这就是我看到无法正确退出程序的问题。使程序在后台运行仍然存在很大的安全风险。
花粉

4
“我认为“退出按钮”很愚蠢”。大多数软件应用程序都提供退出按钮。
IgorGanapolsky 2012年

您说“ //这里停止所有服务”,然后使用finish()。Android服务没有finish()方法。他们有unbindService(mConnection);
IgorGanapolsky

@Squiggles如果您有一个房间,该房间在离开时会自动关闭所有照明并锁定门,则无需担心。
Seshu Vinay 2015年

7

Android应用程序生命周期是为手机用户而非计算机用户设计的。

应用程序生命周期是将Linux服务器转变为消费类设备所需的残酷简单的范例。

Android是基于Linux的Java,是真正的跨平台服务器OS。这就是它如此迅速传播的方式。应用程序的生命周期封装了操作系统的基础现实。

对于移动用户,仅安装或未安装应用。没有运行或退出的概念。实际上,应用程序进程将一直运行,直到操作系统释放它们的可用资源为止。

由于这是Stack Overflow,因此阅读此书的任何人都是计算机用户,必须关闭90%的知识才能了解移动应用程序的生命周期。


我不赞成“计算机用户必须关闭90%的知识”。是的,这就是罗曼·盖伊(Romain Guy)所说的,但这并不是事实。在我看来,带有“退出”按钮的“计算机用户的高级选项”部分将满足每个人的需求。
唐·哈奇

我不知道这个“ Roman Guy”是谁,或者他为什么要引用我。关闭最近执行的任务将退出应用程序,同时停止从应用程序信息中退出也是如此。ADB允许高级用户访问Shell。
Dominic Cerisano

6

与实际实施半适当的Android应用程序生命周期相比,阅读此问答所需的时间更长。

这是一个GPS应用程序,它轮询点并使用线程每隔几秒钟将当前位置发送到Web服务...这可能是在Ted的情况下每5分钟轮询一次更新,然后onStop可以简单地启动Ted的更新活动担心是否找到了(异步Ted,不要像Windows程序员那样编写代码,否则您的程序将像Windows程序一样运行... eww,这并不难)。

我在onCreate中做了一些初始代码来设置活动生命周期中的内容,包括checkUpdate.start();

...

@Override
public void onStart() {
    super.onStart();
    isRemote = true;
    checkUpdate.resume();

    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 0, luh);
}

@Override
public void onPause() {
    isRemote = false;
    checkUpdate.suspend();
    locationManager.removeUpdates(luh);
    super.onStop();
}

这段代码可能是完全错误的,但是可以工作。这是我最早的Android应用程序之一。

Voilà,一个在后台不消耗CPU的应用程序,但由于位于RAM中(尽管不像Android生命周期那样保留RAM),因此立即可以重新打开……一个应用程序始终处于就绪状态,它是一部手机,伙计们。如果某个应用程序要用完所有RAM且无法被操作系统关闭,则事情可能会停止振铃= P这就是为什么操作系统需要能够在后台运行时关闭您的应用程序(如果您的应用程序处于关闭状态)不会浪费资源(顺便说一句),所以让我们编写更好的应用程序。


您不应该从onPause方法中调用super.onStop。这似乎会大大破坏事情。
马特·沃尔夫

1
在阅读了20个左右的哲学答案之后,这些答案仅仅回避了问题……+ 1有了一些代码。
Pacerier,2014年

6

每次通过意图移至下一页时,请使用:

`YourActivityname.this.finish()`;

例:

Intent intent = new Intent(getApplicationContext(), SMS.class);

startActivity(intent);
MainActivity.this.finish();

为了使任何活动都不会在后台运行,并且当您要退出应用程序时,请使用:

MainActivity.this.finish();
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(0);
getParent().finish();

这种退出对我来说就像一种魅力:)


1
它不会退出应用程序,而是涉及Mainactivity。
Sharath 2015年

1
但是要小心-在killProcess和System.exit的情况下,不会调用onPause()。我们对此有一些问题。
Pavel Biryukov 2015年

4

无论如何,如果您想终止应用程序,可以随时致电System.exit(0);


5
System.exit()如果堆栈中有多个活动,则不会终止您的应用程序。使用它的Android开发人员不了解基本的Android应用程序生命周期。阅读此答案
Dheeraj Vepakomma 2012年


2
实际上,System.exit()确实会杀死您的应用程序。但是,如果System.exit()是从main活动之外的其他地方调用的,则android将以较少的堆栈活动重启应用程序。对我来说,这似乎是对干净的故意System.exit的荒谬反应。我的意思是,如果它是div0或某些意外崩溃,则重启它会很有礼貌。但是我记得,这些甚至都不会引起自动重新启动。但无论如何,该应用都会杀死。它可能会重新启动,但这并不意味着它没有被杀死。
杰西·戈登

3

如果您有10,20 ..多个活动正在运行,并且您想完成所有这些活动并退出系统。

application class或中创建一个静态数组constants class.

常数

public class Constants {

public static ArrayList<Activity> activities = new ArrayList<Activity>();

}

MainActivity 在此数组中添加当前活动参考

activity = MainActivity.this; Constants.activities.add(activity);

public class MainActivity extends Activity {

    private ImageView imageButton;
    private Activity activity;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        activity = MainActivity.this;
        Constants.activities.add(activity);

        imageButton = (ImageView) findViewById(R.id.camera);
        imageButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                // existing app.
                if (Constants.activities != null) {
                    for (int i = 0; i < Constants.activities.size(); i++) {
                        Activity s = Constants.activities.get(i);
                        s.finish();
                    }
                }
                //super.finish();
                finish();
                android.os.Process.killProcess(android.os.Process.myPid());
                System.exit(1);
            }
        });
    }
}

1
当用户两次单击按钮时,这可能会使您的应用程序崩溃,尤其是当系统由于任何原因处于高负载状态时。这可以通过从阵列中删除活动来防止。
HopefulHelpful
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.