提问



继续我尝试学习Android,我只读了以下内容:[44]



  问题:用户是否可以选择终止该应用程序
  除非我们放一个菜单选项来杀死它?如果不存在这样的选项,
  用户如何终止申请? 的

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



呵呵,我在Android世界中采取的每一步都遇到了某种问题=(


显然,你无法在Android中退出应用程序(但Android系统可以很好地完全破坏你的应用程序)。该怎么办?我开始认为编写一个充当普通应用程序的应用程序是不可能的 - 用户可以在他/她决定这样做时退出应用程序。这不应该依赖操作系统来做。


我尝试创建的应用程序不是Android Market的应用程序。它不是一般公众广泛使用的应用程序,它是一个将用于非常狭窄的业务领域的商业应用程序。


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


有没有办法让我真的退出应用程序?

最佳参考


这最终会回答你的问题,但我首先要解决你在各种评论中提出的一些问题,以及撰写本文时已经给出的各种答案。我无意改变你的想法 - 相反,这些是为了将来读这篇文章的其他人。



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



数百万人对模型非常满意,因为环境会根据需要关闭应用程序。这些用户根本不会考虑终止Android应用程序,而不是他们想到的终止网页或终止恒温器。


iPhone用户的方式大致相同,因为按下iPhone按钮不一定感觉就像应用程序被终止一样,因为许多iPhone应用程序都会在用户停止的地方启动,即使应用程序确实已关闭(因为仅限iPhone)目前允许一个第三方应用程序。



  正如我上面所说,有很多
  在我的应用程序中发生的事情(数据是
  推送到设备,列出任务
  总是应该在那里,等等。



我不知道什么列表中的任务总是应该在那里意味着,但数据被推送到设备是一个令人愉快的小说,不应该在任何情况下由Activity完成。使用计划任务(通过AlarmManager)更新数据以获得最大可靠性。



  我们的用户登录后无法进行操作
  每次他们接到电话
  和Android决定杀死该应用程序。



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



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



这是任何操作系统的错误。如您所知,您的应用程序被退出的原因是操作系统正在关闭,然后您的更新过程将在流中失败。通常,这不是一件好事。要么在开始时检查更新,要么完全异步地检查更新(例如,通过计划任务),从不退出。



  一些评论建议击中
  后退按钮不会杀死应用程序
  所有(见上面我的问题中的链接)。



按BACK按钮不会杀死应用程序。当用户按下BACK按钮时,它完成屏幕上的Activity。



  它应该只在终止时终止
  用户希望终止它 - 永远不会
  任何其他方式。如果你不能写
  在Android中表现得像的应用,
  那么我认为不能使用Android
  用于编写真实应用程序=(



那么Web应用程序也不行。或者WebOS,如果我正确理解他们的模型(还没有机会玩一个)。在所有这些中,用户不要终止任何东西 - 他们只是离开。 iPhone有点不同,因为它目前只允许一次运行(少数例外),因此离开行为意味着应用程序会立即终止。[45]



  有没有办法让我真正戒烟
  应用程序?



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





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


例如,试图消除文件概念的行动越来越多。大多数Web应用程序都不会强迫用户考虑文件.iPhone应用程序通常不会强迫用户考虑文件。 Android应用程序通常不会强迫用户考虑文件。等等。


同样,越来越多的人试图消除终止应用程序的概念。大多数Web应用程序不会强制用户注销,而是在一段时间不Activity后隐式地将用户注销。与Android相同,在较小程度上,iPhone(可能还有WebOS)。


这需要更多地强调应用程序设计,关注业务目标,而不是坚持与先前应用程序环境相关联的实现模型。缺乏时间或倾向于这样做的开发人员会因为破坏现有心理模型的新环境而感到沮丧。这不是任何一种环境的错,不仅仅是因为风暴在它周围流动而不是通过风暴的山脉的错误。


例如,一些开发环境,如Hypercard和Smalltalk,将应用程序和开发工具混合在一个设置中。除了应用程序的语言扩展(例如,Excel中的VBA,AutoCAD中的Lisp)之外,这个概念并没有引起太多关注。因此,想出应用程序本身存在开发工具的心智模型的开发人员要么必须改变他们的模型,要么将自己限制在他们的模型适用的环境中。[46] [47] [[[48] [49]


所以,当你写:



  和其他杂乱的事情一起
  发现,我认为发展
  我们的Android应用程序不会
  发生。



对你来说,这对你来说似乎是最好的。同样,我建议您不要试图将您的应用程序移植到Web上,因为您在Android应用程序中报告的一些相同问题也会在Web应用程序中找到(例如,没有终止)。或者,相反,有一天,如果您 将应用程序移植到Web上,您可能会发现Web应用程序的流程可能更适合Android,您可以在那时重新访问Android端口。

其它参考1


我想在这里为这个帖子的未来读者添加一个更正。这个特别的细微差别已经逃脱了我的理解很长一段时间所以我想确保你们没有犯同样的错误:


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


简短的回答是,如果你想退出你的应用程序,你必须跟踪你的堆栈中的所有Activity和finish()当用户想要退出时所有这些Activity(并且没有,没有办法迭代通过Activity堆栈,所以你必须自己管理所有这些。)即使这实际上并没有杀死你可能有的过程或任何悬空引用。它只是完成了Activity。而且,我不确定是否Process.killProcess(Process.myPid())]]效果更好;我没有测试过它。


另一方面,如果您可以在堆栈中保留Activity,那么还有另一种方法可以使您的工作变得非常简单:Activity.moveTaskToBack(true)将简单地显示您的过程并显示主屏幕。


长期答案涉及对这种行为背后的哲学的解释。哲学源于许多假设:



  1. 首先,只有当您的应用位于前台时才会发生这种情况。如果它在后台,则该过程将终止正常。但是,如果它位于前台,则OS假定用户想要继续做他/她正在做的事情。 (如果你试图从DDMS中删除进程,你应该首先点击主页按钮,然后将其删除)

  2. 它还假设每项Activity都独立于所有其他Activity。这通常是正确的,例如在您的应用程序启动浏览器Activity的情况下,该Activity完全独立且不是您编写的。浏览器Activity可能会也可能不会在同一个任务上创建,具体取决于其清单属性。

  3. 它假设你的每个Activity都是完全自立的,并且可以在一瞬间被杀死/恢复。(我宁愿不喜欢这个特殊的假设,因为我的应用程序有许多依赖于大量缓存的Activity数据,太大而无法在onSaveInstanceState期间有效地序列化,但是whaddya会做什么?)对于大多数写得很好的Android应用程序,这应该是真的,因为你永远不知道你的应用程序什么时候会在后台被杀掉。

  4. 最后一个因素不是假设,而是操作系统的限制:显式杀死应用程序与应用程序崩溃相同,也与Android杀死应用程序以回收内存相同。/em>这在我们的政变中达到高潮:因为Android无法判断应用程序是退出或崩溃还是在后台被杀,它假定用户想要从他们中断的地方返回,因此ActivityManager重新启动该过程。



当你考虑它时,这适用于平台。首先,这正是当进程在后台被杀死并且用户返回它时发生的情况,因此需要在它停止的地方重新启动它。其次,当应用程序崩溃并呈现可怕的Force Close对话框时会发生这种情况。


说我希望我的用户能够拍照并上传。我从我的Activity中启动了Camera Activity,并要求它返回一张图片。 Camera被推到我当前Task的顶部(而不是在自己的Task中创建)。如果相机出现错误并且崩溃,是否会导致整个应用程序崩溃?从用户的角度来看,只有相机失败,应该将它们返回到之前的Activity。所以它只是重新启动进程,堆栈中的所有相同Activity,减去相机。由于您的Activity应该设计为可以随时杀死和恢复它们,这不应该是一个问题。不幸的是,并非所有的应用程序都可以这样设计,所以它<无论Romain Guy或其他人告诉你什么,我们很多人都面临着问题。因此,我们需要使用变通办法。


所以,我的结束意见:



  • 不要试图杀死这个过程。要么在所有Activity上打finish(),要么moveTaskToBack(true)

  • 如果您的进程崩溃或被杀,并且如果像我一样,您需要内存中现在丢失的数据,则需要返回根Activity。为此,您应该调用startActivity()包含Intent.FLAG_ACTIVITY_CLEAR_TOP标志的意图。

  • 如果你想从Eclipse DDMS的角度杀死你的应用程序,最好不要在前台,否则它会重新启动。您应首先按Home键,然后终止该过程。


其它参考2


我的所有应用程序都退出了按钮......我经常因为它而得到用户的积极评价。我不在乎平台是否以应用程序不应该需要的方式设计。说不要把它们放在那里是有点荒谬的。如果用户想要退出......我向他们提供了完全相同的访问权限。我认为它不会减少Android的运行方式,看起来好像实践。我理解生命周期...我的观察是Android没有做好处理它......这是一个基本事实。

其它参考3


不要将您的应用程序视为单一应用程序。它是一组用户可以与您的应用程序交互的UI屏幕,以及通过Android服务提供的功能。


不知道你的神秘应用做什么并不重要。让我们假设它隧道进入一些超级安全的企业内部网,进行一些监控或交互并保持登录,直到用户退出应用程序。因为您的IT部门命令它,用户必须非常清楚他们何时是IN或OUT因此,你的心态对于用户退出很重要。


这很简单。制作一个服务,在通知栏中发出持续通知,说我在内联网上,或者我正在运行。让该服务执行您的应用程序所需的所有功能。让绑定到该服务的Activity允许您的用户可以访问他们需要与您的应用程序进行交互的UI。并且有一个Android菜单 - >退出(或注销,或其他)按钮,告诉服务退出,然后关闭Activity本身。


对于所有意图和目的而言,这正是您所说的。完成Android方式。查看Google Talk或Google Maps Navigation,了解这种退出的可能性。唯一的区别是,在您的Activity中按下后退按钮可能会让您的UNIX进程处于等待状态,以防用户想要恢复您的应用程序。这与在内存中缓存最近访问的文件的现代操作系统没有什么不同。退出Windows程序后,很可能它所需的资源仍在内存中,等待被其他资源替换,因为它们已被加载,因为它们已不再需要。 Android是一回事。


我真的没有看到你的问题。

其它参考4


这是一次有趣且富有洞察力的讨论,有很多专家参与。我觉得这篇文章应该从Android开发主网站中回放,因为它确实围绕着Android操作系统的核心设计之一。


我还想在这里加两分钱。


到目前为止,我对Android处理生命周期事件的方式印象深刻,为本机应用程序带来了类似Web的体验概念。


话虽如此,我仍然相信应该有一个 Quit 按钮。为什么? ...不适合我或泰德或任何技术专家,但仅限于满足最终用户的需求。


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


这并不意味着有人(操作系统,开发人员?)会根据自己的判断来处理这个问题......它只是意味着我习惯的红色X按钮在哪里。我的动作应该类似于按下按钮时结束通话,按下按钮关闭设备,依此类推等等......这是一种感觉。它本身就带来了满足感。行动确实达到了目的。


即使开发人员可以使用此处给出的建议来欺骗这种行为,但仍然存在感知,即应用程序应该完全停止(最近)由最终用户按需提供的独立,可信和中立的源(OS)运行。

其它参考5


您可以通过按返回按钮或在Activity中调用finish()来 退出。如果你想明确杀掉它,只需从MenuItem调用finish()


Romain并不是说它无法完成,只是它毫无意义 - 用户不需要关心放弃或保存他们的工作或其他什么,因为应用程序生命周期的工作方式鼓励你编写智能软件无论发生什么,都会自动保存并恢复其状态。

其它参考6


这场辩论归结为一个古老的问题,即开发人员是最了解还是用户最了解。人类因素的所有领域的专业设计师每天都在努力解决这个问题。


Ted指出,市场上下载次数最多的应用之一就是App Killer。当人们退出申请时,人们会得到一些额外的血清素。他们习惯使用台式机/笔记本电脑。它可以保持快速移动。它可以保持处理器冷却,风扇不会打开。它耗电量更少。


如果您认为移动设备是一个小得多的船,那么您可以特别欣赏他们过度抛弃您不再需要的东西的动机。现在,Android的开发人员已经推断操作系统最了解并且退出应用程序是古董。我全心全意地支持这一点。


但是,我也相信你不应该挫败用户,即使这种挫败感是出于他们自己的无知。因此,我得出结论,退出选项是一个很好的设计,即使它主要是一个安慰剂按钮,只能关闭一个视图。

其它参考7


特德,你想要完成的事情可能已经完成,也许不是你现在如何思考它。


我建议你阅读Activity和服务。停止使用术语app并开始引用组件,即Activity,Service。我想您只需要了解有关Android平台的更多信息;它是标准PC应用程序的思维方式的变化。事实上,你的帖子中没有任何帖子中有Activity(缺少常见问题解答引用,即不是你的话),这告诉我你需要阅读更多内容。

其它参考8


博客文章何时在Android应用程序中包含一个退出按钮(提示:从不)解释得很远,远比我更好。我希望每个Android开发人员都已经阅读过它。[50]


摘录:



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

  
  许多用户认为退出按钮实现了这一要求
  并要求添加它。开发人员,希望取悦他们的用户,
  有意添加一个。此后不久,他们都失败了。

  
  

      
  • 在大多数情况下,退出按钮只需调用Activity.finish()。这完全等同于点击后退按钮。
      完全正确。服务继续运行并且轮询不断发生。用户可能会认为他们已经杀了应用程序,但他们还没有,很快
      他们会更加生气。

  •   
  • 退出行为现在不明确。您的退出按钮是应该关闭Activity,还是应该还停止所有关联的服务,接收器和警报?应该返回做什么?如果他们点击 Home 会发生什么?如果您的应用有小部件,会发生什么?退出按钮是否应该停止更新?

  •   

  
  解决方案是让后退按钮表现得像你期望的那样
  退出按钮。 BETT呃,只要停止消耗资源
  该应用程序不可见。



继续阅读完整的文章。

其它参考9


我认为重点是除非你有错误的软件,否则不需要退出应用程序。 Android在用户未使用时退出应用程序,并且设备需要更多内存。如果您的应用需要在后台运行服务,您可能需要一种方法来关闭服务。


例如,当应用程序不可见时,Google Listen会继续播放播客。但是当用户完成播放时,总会有暂停按钮关闭播客。如果我没记错,Listen,甚至会在通知栏中放置一个快捷方式,这样您就可以快速进入暂停按钮。另一个例子是像Twitter应用程序这样的应用程序,它不断轮询互联网上的服务。这些类型的应用程序应该真正允许用户选择轮询服务器的频率,或者甚至是否在后台线程中轮询。


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

其它参考10


如果您无法理解如何使您的数据/连接(以及您的应用程序)持续存在,那么您将无法完成Android所需的操作。


那些下载那些可爱的小App Killers的人通常发现他们没有帮助电池寿命或内存使用,但阻碍操作系统做有效管理内存的工作......


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

其它参考11


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


您似乎对Android平台存在一些根本性的误解。我最初对Android应用程序的应用程序生命周期感到有点沮丧,但在得到更多的理解后,我真的很喜欢这种方法。本书将回答您的所有问题以及更多问题。它确实是我为新的Android开发人员找到的最好的资源。


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


顺便说一下,我与Addison-Wesley或任何与本书相关的人或组织没有任何关系。重新阅读我的帖子后,我觉得我有点狂热了。我真的,非常喜欢它,发现它非常有帮助。 :)

其它参考12



  答案:(Romain Guy):用户没有,系统会处理这个问题
  自动。这就是Activity生命周期(特别是
  onPause/onStop/onDestroy)用于。无论你做什么,都不要放一个
  退出或退出应用程序按钮。 对Android而言毫无用处
  应用模型。这也与核心应用程序的方式相悖
  工作




1:完全退出申请可能通常是非强制性的,但它并非无用。如果Windows没有退出选项怎么办?当内存已满并且操作系统不得不猜测你完成了哪些程序时,系统会很慢。我不在乎Romain Guy甚至Larry Page和Sergey Brin所说的 - 这些都是不容置疑的事实:系统运行速度较慢,因为他们必须先杀死任务才能在启动新应用程序之前获取内存。你只是不能告诉我它没有时间杀死一个应用程序!即使来自遥远星球的光也需要时间...... 一些用于允许用户完全关闭应用程序。


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


总之,在最小化和退出之间存在明显的差异,并且对于另一个而言,两者都没有很好的捏合。我们是否在每个螺丝上留下螺丝刀?或者每扇门都有钥匙?我们是否将所有设备都置于高位,直到断路器爆炸,我们需要打开另一台设备?我们是否将洗碗机放在盘子里,每次只取出足够的空间来为一些新的脏衣服腾出空间?我们是否让所有车辆都在车道上行驶,直到 - 哦,没关系。


如果用户想要最小化应用程序,那么最好的方法是最小化它。如果用户想要退出应用程序,那么无论如何最好退出。


它不受欢迎吗?这是Android的观点 - 他们对此不以为然。很多独立新秀Android开发者都对它不屑一顾。


但是当它出现时,就会有良好的编码和糟糕的编码。有很好的程序流模型,并且有不良的程序流模型。


当用户知道他们已完成程序时,将程序留在内存中并不是一个好的程序流程。它完全没有任何意义,并且在启动新应用程序或运行应用程序分配更多内存时会降低速度。


它有点像你的车:有时候你会让它继续运行,比如在停车灯处停车,或者快餐开车,或者停在自动取款机上。但是在其他情况下你确实想把它关掉 - 就像你上班,杂货店甚至家里一样。


同样地,如果你正在玩游戏并且电话响了,是的。暂停游戏并使其继续运行。但是如果用户已完成游戏一段时间,那么一定要让它们退出。


某些应用程序上的退出按钮应该比其他应用程序更加突出。例如,游戏或用户可能想要完全退出的程序应该有明显的退出。其他程序,比如,可能是电子邮件程序,其中退出是不太可能的愿望(以便它可以继续检查电子邮件) - 这些程序不应该浪费主要控制输入屏幕空间的退出选项,但为了良好的程序流程,它应该有一个退出选项。如果某人决定他们不希望他们的邮件程序在覆盖率差的地区,或者在Skype电话或其他什么地方检查电子邮件时,如果他们想要的话,让他们退出电子邮件程序,该怎么办?


暂停和退出是两项至关重要的任务,既不能完成另一项任务。

其它参考13


几乎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上使用任务杀手)。[53]

其它参考14


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



  • 您正在使用您的申请

  • 电话响了

  • 您接听电话

  • 在通话结束时,您将回到
  • 所在地的应用程序


为此,您只需要手机的后退按钮或 Home 按钮(通过短按或长按)和通知栏。


当我退出应用程序时,我只使用 Back 按钮,直到我离开它或 Home 按钮。


这就是我认为大多数应用程序是如何构思的。但是如果我需要某种会话或连接,我会通过登录/注销按钮和通知(标题栏或其他任何内容)向用户说明。这是一个与纯粹的退出风格应用程序相比,风格相当不同。


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


因此,应用程序的整个概念依赖于进入应用程序 - 工作 - 退出应用程序的不同内容。

其它参考15


Hmmmm ...


我认为你不会以正确的方式看到Android应用程序。你可以轻松地做你想做的事情:



  • 应用程序Activity保存/恢复状态,就像开发人员生命周期文档中所鼓励的那样。

  • 如果在恢复阶段需要某些登录(没有可用的登录/会话信息),则执行此操作。

  • 最后添加一个按钮/菜单/超时,在这种情况下,您将执行finish()而不保存登录和其他会话信息,隐式地结束应用会话:所以如果应用程序启动/带到前面它将再次开始一个新的会议。



这样你就不会真正关心应用程序是否真的从内存中删除了。


如果你真的想要从内存中删除它(这是不鼓励的,BTW用于什么目的?)你可以在java.lang.System.exit(0)(或者restartPackage(..)onDestroy()结束时有条件地删除它? )。当然只在你想要真正结束应用程序的情况下才这样做,因为onDestroy()是Activity正常生命周期的一部分而不是应用程序结束。

其它参考16


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

其它参考17


Linux内核有一个名为Out-of-memory killer的功能(如上所述,策略可在用户空间级别配置,内核不是最佳的,但绝不必要)。[54]


它被Android大量使用:



  • OOM杀手不适合用户空间 [55]

  • Android Notes (OOM杀手信息 - 您可以在Android上配置OOM功能)[56]

  • Android移植真实目标 [57]



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



  • Autokiller/配置Android的内部任务杀手


其它参考18


您显然已在finish()命令中找到了所需的答案。这不会从内存中移除你的应用程序,但Android会在需要资源时这样做,所以它不会有任何区别,你不会明确地这样做。[58]


我只想补充一点,为了获得应用程序退出通常具有的全部效果,您可能希望将应用程序的状态重置为在设备启动后首次运行时的状态,就在你对所有Activity调用finish()之前。这样,如果用户再次选择你的应用程序,它似乎已经新鲜运行,没有任何状态从模拟退出之前的点遗留下来。


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


这种方法允许您实现退出命令的目标,而不违反Android的操作系统手中的操作系统资源管理(包括关闭应用程序)的理念。


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


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


关于system.exit(0):


如果你决定使用system.exit(0)以粗鲁的终结关闭你的应用程序(例如,由于最后的按钮按下),那么我会警告你,虽然对我来说这有用,但在某些情况下案例是我能够关闭应用程序而没有留下任何痕迹的唯一方法,当你使用这种方法时,在果冻豆中会发生一个小故障。


具体来说,如果您使用最近的应用程序列表打开您的应用程序,然后使用后退按钮关闭应用程序(通过system.exit(0)实现该关闭),则最近的应用程序列表将再次可见,因为它将从未关闭过。然后,如果您点击该列表中的应用程序条目,从同一个已打开的最近的应用程序列表中再次运行,则不会有任何响应。


我怀疑造成这种情况的原因是最近的应用程序列表持续引用您的应用程序,由于您已使用system.exit(0)关闭了应用程序,该应用程序已失效。使用finish()更加文明地关闭你的应用程序可能会以允许它刷新其最近的应用程序列表的方式告知操作系统,但system.exit(0)显然不会这样做。


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

其它参考19


我同意泰德。我知道退出应用程序不是
Android方式,但它似乎不应该被排除在外。这里
您可能希望真正退出应用程序的原因有三个(不是
只是Activity):



  1. 用户可能想要控制哪个应用被杀死了
    内存不足的情况。如果重要的应用A在后台运行,
    然后你可能想要在完成它之后退出应用程序B.
    该应用程序A不会被操作系统杀死。

  2. 如果您的应用程序将敏感数据缓存在内存中,您可能会
    喜欢杀死应用程序,以便病毒/蠕虫/流氓应用程序无法实现它。我
    知道安全模型应该防止这种情况,但以防万一......

  3. 如果您的应用程序使用资源(如网络,CPU,传感器等)
    这可能会对手机产生负面影响,从而确保这一点
    释放这些资源就是退出应用程序。我明白
    表现良好的应用程序应该在不需要时释放资源。但同样,退出应用程序似乎是确保这一点的合理方式。


其它参考20


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


从本质上讲,因为你不能退出操作系统,你只需转换成自我创造的虚无。

其它参考21


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

其它参考22


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


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


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


我认为,如果你编写了一段很好的代码,在正确的时刻和条件下做正确的事情(更新,保存和推送)并使用正确的东西(服务和接收器)它会很好地工作,没有人会抱怨。


但要做到这一点,你必须学习和学习Android上的工作原理。
无论如何,这是我向用户提供退出按钮的解决方案。


我在每个Activity中创建了一个始终可见的选项菜单(我是一个超级Activity)。


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


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。请看看那些标志;那些将清除我的所有backstack调用我的DashBoard Activity,这是我的主页Activity。


所以在我的Dashboard Activity中我在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的所有正确流程)应用程序仍然在最近的Activity(但它是空白的)。


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


我还要挖掘更多,以便将它删除。

其它参考23


没有退出功能,应用程序开发人员就可以杀死自己的应用程序,这是非常糟糕的设计。


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

其它参考24


我花了更长的时间来阅读这个Q& A,而不是真正实现一个半适当的Android应用程序生命周期。


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


我在onCreate中做了一些初始代码来设置Activity生命周期的东西,包括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à,一个ap在后台没有消耗CPU的应用程序,但它立即准备重新打开,因为它在RAM中(虽然不像Android生命周期那样持有RAM)...应用程序总是准备好,它是一个电话,伙计们/gals。如果一个应用程序耗尽了所有RAM并且无法被操作系统关闭那么事情可能会停止响铃= P这就是为什么操作系统需要能够关闭你的应用程序时在后台(如果你的应用程序不是资源耗尽它不会被BTW关闭),所以让我们写下更好的应用程序。

其它参考25


要在任何时候关闭应用程序,请在Intent中使用FLAG_ACTIVITY_CLEAR_TOP标志然后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生命周期的情况下工作。

其它参考26


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


`YourActivityname.this.finish()`;


示例:


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

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


因此,不会在后台运行任何Activity,并且当您想退出您的应用时,请使用:


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


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

其它参考27


Android应用程序生命周期专为移动电话用户而非计算机用户设计。


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


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


对于移动用户,只是安装或未安装应用程序。没有跑步或退出的概念。实际上,应用程序进程应该运行,直到操作系统为其持有的资源释放它们。


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

其它参考28


在任何情况下,如果您想终止您的申请,您可以随时拨打System.exit(0);

其它参考29


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


application classconstants class.中创建静态数组


常量


public class Constants {

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

}


MainActivity 在此阵列中添加当前Activity参考


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);
            }
        });
    }
}