退出申请不赞成?

Ted*_*Ted 1131 android

继续我学习Android的尝试,我只是阅读以下内容:

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

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

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

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

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

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

有没有办法让我真的退出申请?

Com*_*are 1271

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

关键是我无法让Android确定何时终止我的应用程序.这必须是用户的选择.

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

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

正如我上面所说,我的应用程序中发生了很多事情(数据被推送到设备,列表中的任务总是存在,等等).

我不知道"列出任务总是应该在那里"是什么意思,但"推送到设备的数据"是一个令人愉快的小说,在任何情况下都不应该由活动完成.使用计划任务(via AlarmManager)更新数据以获得最大可靠性.

我们的用户每次拨打电话时都会登录并且无法执行此操作,并且Android决定终止该应用.

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

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

这是任何操作系统的错误.如您所知,您的应用程序被"退出"的原因是操作系统正在关闭,然后您的更新过程将在流中失败.一般来说,这不是一件好事.检查启动时的更新或完全异步检查更新(例如,通过计划任务),从不退出.

一些评论表明,按下后退按钮并不会杀死应用程序(请参阅上面的问题中的链接).

按BACK按钮不会"杀死应用程序".当用户按下BACK按钮时,它完成屏幕上的活动.

它应该只在用户想要终止它时终止 - 从来没有任何其他方式.如果您无法编写Android中的行为类似的应用程序,那么我认为Android不能用于编写真实应用程序=(

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

有没有办法让我真的退出申请?

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


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

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

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

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

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

所以,当你写:

除了我发现的其他混乱的东西,我认为开发我们的Android应用程序是不会发生的.

对你来说,这对你来说似乎是最好的.同样,我会建议您不要尝试将应用程序移植到Web上,因为您在Android应用程序中报告的某些问题也会在Web应用程序中找到(例如,没有"终止").或者反过来说,如果有一天你端口您的应用程序到Web,您可能会发现Web应用程序的流量可能是针对Android更好的匹配,你可以在那时再讲一个Android端口.

  • "请注意,我的用户是专业人士,使用该设备的唯一目的是使用我试图移植到Android的应用程序." 实际上,你已经另有说明("每次他们接到电话时都不能这样做" - "电话"不是你的应用程序).此外,除非您构建自己的设备,否则无法阻止人们安装其他应用程序. (65认同)
  • @SomeCallMeTim:不,这不是使用`killProcess()`的正当理由.编写更好的iOS代码是一个正当理由. (23认同)
  • @CommonsWare:对不起,但这是一个对我来说毫无用处的陈词滥调.我正在移植我支付给端口的代码.我应该花两倍的时间来做端口,重写代码,还是以降低雇主成本的方式完成,让他们能够更快地在Android上放置更多游戏?无论如何,这是一个完全学术性的问题:他们不希望我对他们的引擎做出如此重大的改变,因为我无法测试iOS上的变化.而且这是完全错误的:将Singleton模式用于适当的对象并没有"坏".Android只是破坏了WRT NDK应用程序. (23认同)
  • 一个想法在我脑海中漂浮:如果我只是将整个应用程序重写为服务,并将该服务视为实际应用程序 - 也许这会更好?然后,我可以"愚蠢"活动(就像Android想要的那样)只提供服务中包含的数据.在那种情况下,我可以保持登录状态和其他东西.使用*startForeground(int,Notification)*我几乎可以阻止Android杀死服务......? (20认同)
  • @Ted用于更可靠的重新初始化,也许您可​​以最小化存储在活动或服务本身的状态量.相反,将大部分状态和代码放在一个单独的类中,每次活动或服务启动时,您都会从头开始重新创建. (10认同)
  • 另外,如果你依靠长期的TCP连接进行会话管理,你肯定会缓存用户的凭据吗?对于移动应用程序,期望用户仅仅因为设备暂时丢失网络而手动重新建立会话似乎有点疯狂. (6认同)
  • @BarryFruitman App杀手不是必需的,实际上会破坏许多功能正常的应用程序.不在前台的活动不使用CPU,因此没有"让它闲置"的问题,即缓存在内存中.如果它需要内存,操作系统将会杀死它.如果一个应用程序正在使用CPU但没有在前台运行,那么它正在运行一项服务; 即,不是"绝对不做". (6认同)
  • @BarryFruitman几乎在每个平台上,即使应用程序关闭后,它仍然会缓存在RAM中,直到系统有理由用RAM替换它在RAM中.Android没有什么不同(除了在Android的情况下,允许使用的堆是有界的)."封闭"和"空闲"之间的区别在Android上变得有意义的唯一时间是在非常高的内存负载下,并且随着手机接近2GiB的RAM,人们不太可能经常遇到它们.(并且100%的RAM始终供电,因此关闭内存驻留的空闲应用程序不会影响电池寿命.) (6认同)
  • @SomeCallMeTim:"应用程序甚至不会得到onDestroy()调用,直到另一个实例有机会运行,重复使用该过程" - 让我持怀疑态度,但即便如此,应该有办法解决问题而不诉诸到`killProcess()`(例如,检测NDK库中`Application`对象的变化).我建议您打开一个新的SO问题,以便我们可以获得有关您正在使用的确切模式和您感知的问题的更多信息. (5认同)
  • 操作系统对活动进行生命周期管理不是一个不可改变的法则(如果我们都是为iPhone编写的话).许多用户更喜欢温度模糊的感觉,知道应用程序在注销后关闭,更不用说避免额外的按键返回到主屏幕.在等待操作系统执行操作时,如果应用程序在完全没有任何操作的情况下保持闲置也是一种耗尽或资源.如果它不是应用程序杀手不会那么受欢迎(和必要). (5认同)
  • 马克:谢谢你的好总结.泰德:我们正在慢慢发现你需要什么功能,比如长寿会议.如上所述,您可以使用服务.此外,我怀疑您每次与服务器交互时都需要登录到您的应用程序 - 当然,您可以保留会话ID令牌吗? (4认同)
  • 虽然您的答案对于Java应用程序是正确的,但是有充分理由完全终止应用程序:如果您正在使用移植的应用程序的NDK代码(例如,从iPhone移植),那么就不会期望该进程被回收,因此,如果应用程序"退出"并重新启动,则会有一堆具有全局或静态值的代码,这些代码将处于无效状态.事实上,finish()在这里甚至没有帮助; 应用程序甚至不会获得onDestroy()调用,直到另一个实例有机会运行,重用该进程.android.os.Process.killProcess(android.os.Process.myPid()); 作品.:) (4认同)
  • 我重新尝试使用Android,然后再次遇到这个退出业务.无法完全销毁/退出服务/其他任何一个主要问题是它非常容易出错!如果我可以重新启动一个应用程序(真实的)我会知道所有变量都被重置 - 所有变量都被初始化为它的起始点.现在,我需要手动完成所有这些操作.因此,如果我添加一个变量,然后忘记重置,当我"重新启动"应用程序时我会遇到问题,因为soem变量(和东西)将会挥之不去.这仍然是我无法理解任何人如何防守的事情. (4认同)
  • @Jon O:是的,但CPU并不是唯一有限的资源.未使用的应用程序也浪费RAM.操作系统可能会自动终止它们,但它并不总是按照人们预期或喜欢的顺序执行.对于应用程序杀手,我现在倾向于同意你的意见,但我仍然认为一个好的老式"关闭"按钮对于某些应用来说是一个好主意. (4认同)
  • @BarryFruitman 1)"免费"通常被实现为"表明其他人可以在需要时使用它".因此,如果您立即重新打开应用程序,几乎所有内容都会成为缓存命中.2)同意; 重读!:) 3)不确定但是当争用发生时,IIRC应用程序以LRU顺序关闭.4)没有这样的事情.如果它没有被使用,它只会浪费; 未使用的RAM =免费缓存!http://geekfor.me/faq/you-shouldnt-be-using-a-task-killer-with-android/ < - 请参阅附录,特别是. (4认同)
  • "使用startForeground(int,Notification)我几乎可以阻止Android杀死服务......?" 假设您的用户不介意在状态栏中显示图标,这应该可行.或者,换句话说,即使使用startForeground()后,如果你的服务仍然因为低内存而被杀死,你会遇到更大的问题. (3认同)
  • @SomeCallMeTim:Dianne Hackborn已正式认可您的方法,如果您需要它:http://groups.google.com/group/android-developers/browse_thread/thread/b48f0fa3784f8e27 - 就个人而言,我仍然认为我们可以找到替代方案. (3认同)
  • @CommonsWare:感谢您告诉我有关该主题的信息.我和NDK小组一样,但我只收到NDK小组的电子邮件,所以我从未见过这个讨论. (3认同)
  • 优势很多:开发人员不必在99%的时间内考虑它.用户不必担心.应用是一致的.这不是现代设备的问题.你当然可以等待50ms来接听你的电话.鉴于我从Android开发者那里看到的代码质量(特别是在StackOverflow上),我很高兴.现在......我想要一个退出按钮来杀死操作系统级别的进程(及其子进程)吗?是的,但滥用此功能可能会导致应用程序使用更多电池(重新启动应用程序意味着将所有内容再次移至内存等) (3认同)
  • 感谢您的回答commonsware =)我完全同意。实际上,昨天与同事一起讨论这些问题时,我在Android和网页之间进行了参考和比较。我确实感觉到Android试图模仿某种形式的网页,但这并不是我所说的“真正的应用程序”(尽管这当然是主观的)。如果该应用程序可以转换为WebApp,那么我可能只是创建一个网页并要求用户启动其Web浏览器。但事实并非如此=( (2认同)
  • "你的意思是我有更大的问题?" 我的意思是,这种情况发生的唯一方法是设备是否存在严重的内存问题,可能需要重启.startForeground()服务是倒数第二个必须被内存回收杀死(最后是前台活动).由于Android应用程序并不具有无限的堆大小,发生这种情况的唯一办法可能是因为大量的应用程序被滥用startForeground()或者操作系统本身漏水RAM. (2认同)
  • 关于"数百万人对环境根据需要关闭应用程序的模型非常满意." 数百万人在响铃后还要等几秒钟才能接听电话,因为Android必须首先通过查杀你几周没用过的应用程序来释放内存.我说如果用户想要退出运行其应用程序的JVM,以便在需要时可以立即获得内存,那么请务必让他们!〜杰西 (2认同)
  • "数百万人还需要等待几秒钟才能在铃声响起后接听电话,因为Android必须首先通过杀死你几周没用过的应用程序来释放内存." - >幸运的是,事实并非如此.Android应用程序通常比这更快地被杀死.不要相信"假的"任务管理器以及事实上Android确实在任务管理器中显示应用程序的事实,这并不意味着它正在使用内存,事实上,你宁愿不得不争取拥有你的记忆在任何时候都不会一直被杀,而不是担心相反. (2认同)
  • @Pacerier 的好处优于您可能获得的几毫秒。另一方面,CPU 可能会妨碍您的手机。记忆?大多数现代设备都有足够的内存来提前计划,Android 做得很好(我一直使用 Nexus 设备)。iOS 也是如此,内存模型工作正常。可以改进吗?当然,但我想说还有比这更重要的事情。例如,Activity 和 Fragment 之间生命周期的可怕状态就是其中之一。 (2认同)
  • 我真的不同意它就像一个网页.网页在服务器上100%运行,因此任何时候都可以访问所有用户.但是应用程序确实在用户的终端(例如移动电话)内运行,并且可以在窗口中等同于"最小化".同样地,人们在完成某些事情时不会最小化,同样适用于应用程序恕我直言.想象一下记事本应用程序.如果我想继续我的旧笔记,我按下主页按钮,然后再返回到该笔记.但是,如果我想从一个空洞的空白开始.然后应该可以杀死应用程序然后重新开始. (2认同)
  • 完全同意塞巴斯蒂安·尼尔森的观点。作为用户,我可以说移动应用程序和网络应用程序之间的巨大区别在于网络应用程序不在我的设备上运行并且不会消耗我的资源。所以我不关心我关闭浏览器选项卡离开它后它会做什么。但是,当我完成应用程序的工作并关闭它(例如任何游戏或其他“重”应用程序)时,我真的想立即关闭它。我不希望它离开,直到操作系统决定杀死它。 (2认同)

Nei*_*aft 289

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

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

简短的回答是,如果你想退出你的应用程序,你必须跟踪你的堆栈中的所有活动以及finish()当用户想要退出时的所有活动(并且没有,没有办法遍历活动堆栈,所以你必须自己管理所有这些).即使这实际上并没有杀死你可能拥有的过程或任何悬空参考.它只是完成了活动.另外,我不确定是否Process.killProcess(Process.myPid())更好; 我没有测试过.

另一方面,如果您可以在堆栈中保留活动,那么还有另一种方法可以让您的工作变得非常简单:Activity.moveTaskToBack(true)只需将您的流程设置为背景并显示主屏幕即可.

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

  1. 首先,这只发生在您的应用程序位于前台时.如果它在后台,则该过程将终止正常.但是,如果它位于前台,则OS假定用户想要继续做他/她正在做的事情.(如果你试图从DDMS中删除进程,你应该首先点击主页按钮,然后杀死它)
  2. 它还假设每项活动都独立于所有其他活动.这通常是正确的,例如,在您的应用程序启动浏览器活动的情况下,该活动完全独立且不是您编写的.浏览器活动可能会也可能不会在同一个任务上创建,具体取决于其清单属性.
  3. 它假定您的每项活动都是完全自立的,并且可以在一瞬间被杀死/恢复.(我宁愿不喜欢这个特殊的假设,因为我的应用程序有许多依赖于大量缓存数据的活动,太大而无法有效地序列化onSaveInstanceState,但是whaddya会怎么做?)对于大多数写得很好的Android应用程序,这应该是真的,因为你永远不知道什么时候你的应用程序会在后台被杀死.
  4. 最后一个因素不是假设,而是操作系统的限制: 明确杀死应用程序与应用程序崩溃相同,也与Android杀死应用程序以回收内存相同. 这最终导致了我们的优势:由于Android无法判断应用程序是退出或崩溃还是在后台被杀,它假定用户想要返回他们中断的位置,因此ActivityManager重新启动该过程.

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

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

所以,我的结论是:

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

  • 杀戮过程有时非常有用 - 例如在编写使用本机代码的游戏时.杀死进程意味着立即将所有已分配的内存释放回系统. (13认同)
  • 感谢您提供实际答案(`moveTaskToBack()`是我正在寻找的).很多人只是说"不,你是一个想要退出你的应用程序的白痴." 甚至没有考虑到可能存在你想要它的情况(例如登录失败). (12认同)
  • 对于任何关心的人,Process.killProcess演示与System.exit()完全相同的行为 (10认同)
  • 实际上,自从我再次开始使用Android以来,我正在完成所有活动(在任何时间点只有一个活动处于活动状态),然后我调用System.exit(0); 在我的服务中 - 这也是我想要的.我知道大多数人都会说"不要这样做",但我完全按照我想要的行为...... (8认同)
  • 从常见的AtivityBase派生所有活动.然后按住一个标志强制关闭应用程序,在onResume上检查是否设置了force close标志.如果是这样,调用System.exit(0); 这将在整个活动堆栈中级联,最终完全关闭应用程序. (6认同)
  • `Android无法判断应用程序是退出或崩溃还是在后台被杀 - WTF?这就是进程返回代码的用途!Android是否放弃了那些尽管是基于Linux的? (4认同)
  • System.exit(0);/System.runFinalizersOnExit(true);/android.os.Process.killProcess(android.os.Process.myPid()); < - 他们都是一样的. (3认同)
  • @Niel:感谢这个知识宝石,并且非常清楚地呈现它并且对事物非常实用.这肯定会为我节省无数小时的实验活动生命属性. (3认同)

and*_*rkz 178

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

  • 你用什么机制戒烟? (25认同)
  • +1,因为不幸的是,它在这个时间点做得并不好(但我仍然想尝试按照设计做的事情,所以它让我陷入困境) (15认同)
  • 是啊..地狱与'不是android标准'.. Android是强大的coz,它使人们可以实验..如果它提供API做某事,怎么能说它不是Android标准?我无法消化所有那些"哲学"的答案.您使应用程序牢记您的用户.如果他们感到高兴或者他们想要看到这个特征,那么即使那些所谓的哲学家反对它,实施它也是绝对正确的. (13认同)
  • @Igor finish() - 活动不会杀死应用程序(扩展Application).因此,即使没有任何活动处于活动状态,设置仍然是活动的和实际的,这样当活动尝试访问它们时,它们将是以前使用过的.System.exit(0); 另一方面杀死应用程序,这样当再次启动时,应用程序将不得不重新初始化设置.这是我手动更新我的应用程序时所需要的,因为我经常更改数据的格式,我需要立即重新启动它们. (4认同)

Eri*_*ric 143

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

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

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

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

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

  • @Eric,你不要**因为你正在逃避它而看**问题.您只需使用在旧"程序模型"上运行的*another*程序来执行"Android模型"无法完成的操作.要查看"Android模型"的问题,您必须想象您没有将任务委派给Linux/Windows盒子.你必须想象你只能用只运行"Android模型"的盒子来做你从前端到后端的所有**.然后,你会发现"Android模型"的局限性与天空一样明显. (3认同)

Pau*_*aul 71

This is an interesting and insightful discussion with so many experts contributing. I feel this post should be looped back from within the Android development main website, because it does revolve around one of the core designs of the Android OS.

I would also like to add my two cents here.

So far I have been impressed with Android's way of handling lifecycle events, bringing the concept of a web-like experience to native apps.

Having said that I still believe that there should be a Quit button. Why? ... not for me or Ted or any of the tech gurus here, but for the sole purpose of meeting an end user demand.

Though I am not a big fan of Windows, but long back they introduced a concept that most end users are used to (an X button) ... "I want to quit running a widget when 'I' want to".

That does not mean someone (OS, developer?) will take care of that at its/his/her own discretion... it simply means "where is my Red X button that I am used to". My action should be analogous to 'end a call on pressing of a button', 'turn off the device by pressing a button', and so on and so forth ... it's a perception. It brings a satisfaction per se that my action indeed achieve its purpose.

Even though a developer can spoof this behavior using suggestions given here, the perception still remains i.e. an application should completely cease to function (now), by an independent, trusted and neutral source (OS) on demand from the end user.

  • 实际上,这相当于向用户说谎,给他们一种温暖,模糊的感觉.最终,让过去的遗物落到路边更好,以免它们继续成为技术的永久固定装置.移动和Web是新平台,预计其行为与桌面不同.而且至少,Android的生命周期决定似乎正在吸引用户:随着我最大的应用程序通过其2周年纪念日,我注意到最终用户请求"退出"按钮干涸,因为他们已经习惯了新平台. (3认同)
  • 我也没有找到所有建议背后的理由说"不要杀死这个过程".在我看来,顾客永远是对的,所以在被要求提供退出按钮并"向用户撒谎以给他们一种温暖,模糊的感觉"之后,如果这就是他们想要的东西,那会有什么问题?这部分就是编写好的应用程序的全部内容.大多数用户不知道或不关心真正发生了什么,但如果他们喜欢你的应用程序并且它做了他们想要和期望的事情,他们会回来购买更多你的应用程序.这就是我们都想要的,不是吗?或者我错过了什么? (3认同)
  • 对.好的'Windows Mobile提供与Windows PC相同的X按钮,除了它实际上没有退出应用程序,它只是"智能最小化"它.许多用户可能从未发现应用程序没有真正退出.(该方法效果很好,但如果您使用.NET Compact Framework,则不会通知应用程序已发生这种情况,因此无法选择释放资源或实际退出.) (2认同)
  • @Jon你推荐什么?不在应用程序的任何位置提供"退出"选项? (2认同)

Chr*_*Orr 37

可以退出,或者通过按下Back按钮或调用finish()你的Activity.如果您想明确地将其删除,只需finish()从a 调用MenuItem即可.

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

  • 如果它填满了一个目的,它就没有意义,而在我们的应用程序中,它就是这样做的.例如,我们想在退出应用程序时检查更新.我们无法退出应用程序,然后无法进行更新.一些评论表明,按下后退按钮并不会杀死应用程序(请参阅上面的问题中的链接). (5认同)
  • 正如Romain所说,核心应用程序的运作方式并非如此.因此,如果用户习惯按"退回"退出应用程序,那么他们似乎可以继续使用您的应用程序而不是明确选择退出?您可以在启动时执行更新检查,或者使用onDestroy(),或使用重复警报..它似乎不需要由用户触发. (2认同)

Cha*_*ock 31

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

Ted指出,市场上下载次数最多的应用之一就是"App Killer".当人们退出申请时,人们会获得一些额外的血清素.他们已经习惯了桌面/笔记本电脑.它可以让事情快速发展.它可以使处理器保持冷却并且风扇不会打开.它使用更少的电力.

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

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

  • 当你的宗教信仰说Android任务杀手是"不必要的",但是使用ATK杀死没有业务运行的愚蠢任务会改变操作系统从正常速度的~1-5%爬回到正常速度的100%(测量)每次系统达到50MB免费低端时,100%ATK使用超过2年的100%时间,**你的宗教信仰是错误的** (10认同)
  • 是的,有一个'退出'按钮确实是用户友好的.如果用户有5项活动,用户还会如何退出应用程序呢?当然,他们可以多次按回,但我不认为他们会这样. (8认同)
  • 只有5?Android 2.2网络浏览器让我花几分钟点击后退按钮,直到我最终退出 (4认同)
  • 当他们开发WORKS的内存管理器时,我会开始听android的开发人员.截至Froyo,它工作得非常糟糕,杀掉随机应用程序,重新启动不需要的应用程序(并且没有Intents合法启动它们),以及OTOH,当内存达到50MB空闲时,减速到完全爬行. (3认同)

Aar*_*ron 29

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

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

  • 一个应用程序可以包含服务和活动,听起来你的应用程序可能需要两者.该活动仅是UI部分. (4认同)

Dhe*_*.S. 23

博客文章时包括在Android应用中退出按钮(提示:切勿)解释的那样远,远远比我可以更好.我希望每个Android开发者都已经阅读过它.

摘录:

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

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

  • 在大多数情况下,退出按钮只是调用Activity.finish().这完全等同于按下后退按钮. 究竟. 服务不断运行,轮询不断发生.用户可能认为他们已经杀了应用程序,但他们没有,很快他们会更加恼火.
  • 退出行为现在不明确.您的退出按钮是应该关闭活动,还是应该还停止所有关联的服务,接收器和警报?该怎么Back办?如果他们打了Home相反会发生什么?如果您的应用有小部件,会发生什么?退出按钮是否应该停止更新?

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

继续阅读完整的文章.

  • 退出和返回并不总是用于相同的目的.以潘多拉为例.当你回击退出这个应用程序时,它不会退出应用程序(让它作为服务在后台播放). (3认同)
  • @ DheerajV.S.,只要应用程序不可见,只需停止消耗资源?**错误的建议.****非常.****非常x99.**每当我尝试给自己发送照片时,我必须让应用程序保持整整5分钟,因为如果我最小化它,它会停止发送电子邮件照片.正确,我不能使用我的手机整整5分钟只是因为一些开发人员认为应用程序应该只在可见时运行.现在想象发送一个像视频一样的大文件...... (3认同)
  • 神话与否,原始用户与否,但几乎所有在任何平台和操作系统上编写的UI软件都实现了退出/关闭/退出按钮.你还怎么实现呢? (2认同)

Jes*_*don 20

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

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

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

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

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

它不受欢迎吗?这是Android的观点 - 他们对此不以为然.许多独立的新手Android开发者对此赞不绝口.

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

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

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

同样,如果你正在玩游戏并且手机响了,是的.暂停游戏并保持运行.但是如果用户已完成游戏一段时间,那么一定要让他们退出.

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

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

  • HoGo,谢谢你的评论.当然,我不同意.具体来说,尽管我可以说,你的观点是,由于一些用户不知道他们应该做什么,因此不要让任何用户做他们应该做的事情,甚至不知道他们应该做什么.如果android有办法准确知道它是否应该终止应用程序而不是最小化它,那么很好.但事实并非如此,并且迫使所有用户在想要退出时始终处于最小化状态,导致设备性能不佳. (3认同)
  • “如果用户想最小化一个应用程序,那么最好的办法就是最小化它。如果用户想退出一个应用程序,那么无论如何最好退出。” - 有一件事(基于十多年的经验):用户很少知道他们想要什么。如果你不帮助他们,你将不得不改变它。关于上面的示例:让我给您提供其他示例:您正在制造汽车并且手头有一张桌子可以放东西。您是否总是把所有必要的工具正确地放在柜子里,或者把最常用的工具放在手边?只是把一个大的旧旧的放好,有地方放新的? (2认同)

Jay*_*ren 19

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

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

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

  • 除了我发现的其他混乱的东西,我认为开发我们的Android应用程序是不会发生的.它有太多的"大哥" - 正在发生的事情,Android告诉我应该运行什么应用程序.我作为程序员应该有这个选择,而不是google或android =( (5认同)
  • 您的活动 - 活动用户界面 - 当另一个应用程序出现在您的顶部时,或者您按回或其他任何内容时消失.用户不与他们交互,因此如果用户长时间不回来,保存状态是最安全的,等等,如您所知.没有什么可以阻止你编写"服务"来保持正在进行的工作在后台发生,比如接收数据推送或其他什么.当您使用其他应用时,Google Talk不会停止工作.与音乐播放器相同.看看那里的其他应用程序以及它们如何工作. (3认同)
  • 您应该能够保存凭据,这样用户无需在每次拨打电话或离开应用程序时都登录.我建议看一下Android的生命周期.当应用程序暂停,停止或销毁时,您可以保存所有相关数据,这样当应用程序再次打开时,它就会像他们离开时一样.用户甚至不需要知道应用程序曾被停止过. (3认同)
  • 我发现这个问题仍然存在,在我提出它四年后 =) 我确实将它作为一项服务在后台运行,但我添加了退出按钮,因为我仍然觉得 - 四年后 - 这是它的必要而且很重要。我看到越来越多的应用程序也具有这种功能(例如 Skype)。 (2认同)

Dan*_*Dan 19

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

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

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

  • @Dan,如果我完全退出我已经完成一周的应用程序阻止Android操作系统的工作,我怎么可能远程可能?所以有更多的免费记忆.这不可能阻碍android!不过,它确实可以在以后加快速度!如果我知道我已经完成了应用程序一段时间,它完全没有任何意义.它只占用内存,迟早,我会推出一个新的应用程序,操作系统会有一个额外的延迟,因为它必须杀死一些我知道WEEKS之前完成的应用程序. (3认同)

小智 18

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

您似乎对Android平台存在一些根本性的误解.我也曾经在第一次与Android应用程序的应用程序生命周期有点沮丧,而是来到了一个更深入的了解之后,我是来真的很喜欢这种方法.本书将回答您的所有问题以及更多问题.它确实是我为新的Android开发人员找到的最好的资源.

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

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

  • 我厌倦了移动设备有多少"资源"的咒语.醒来,它们运行超过500Mhz并且有大量内存.我的旧戴尔Axim有128MB的RAM.目前的设备通常超过512RAM并在1GHZ上运行!这比我的旧Pentium 90Mhz高10倍,而且我没有听到ppl说"非常有限的资源"这个和那个.是时候醒来闻到咖啡了 - 我们现在是2010年,而不是80年代. (8认同)
  • 谢谢你的书尖.如果可以的话,我会看看它,如果我决定继续使用Android端口.仅举几例:我们的用户在计算机方面并不是最新的.我很难让他们使用Android中的NotificationBar.太小了(他们有大手指呵呵).它对他们来说是一个不同的世界,所以我们需要保持简单,没有用户的选择.为此我们构建了我们的.NET解决方案 - 不要给他们一个选择=) (2认同)

And*_*ies 15

几乎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.
Run Code Online (Sandbox Code Playgroud)

现在要杀死你的应用程序,提供一个kill()方法:

android.os.Process.sendSignal(pid, android.os.Process.SIGNAL_KILL);
Run Code Online (Sandbox Code Playgroud)

现在,只要你需要你的应用程序自杀,只需输入应用程序上下文,并调用你的kill方法!

((MySuicidalApp) context.getApplicationContext()).kill()
Run Code Online (Sandbox Code Playgroud)

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


Sol*_*n14 14

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

  • 您正在使用您的应用程序
  • 电话响了
  • 你接听电话
  • 在电话会议结束时,您将在同一个地方回到您的应用程序

要做到这一点,您只需要手机的Back按钮或Home按钮(通过短按或长按)和通知栏.

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

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

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

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


小智 12

Hmmmm ...

我认为你没有看到Android应用程序正确的方式.您可以轻松地执行您想要的操作:

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

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

  • 最后添加一个按钮/菜单/超时,在这种情况下,您将在finish()不保存登录和其他会话信息的情况下执行操作,隐式地结束应用程序会话:因此,如果应用程序启动/再次启动,它将启动新会话.

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

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


Tom*_*m R 11

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

  • 什么@JesseGordon说,*和*另一个方面,为什么退出是有道理的:如果我*不退出这个资源密集型应用我知道我不会再使用一个月,操作系统有时会错误地当资源变得稀缺时杀死一些*其他*应用程序,同时让这个无用的资源占用应用程序运行...使其他应用程序需要更长时间才能恢复. (3认同)
  • 在某些情况下,一定要退出应用程序才有意义。如果您每月使用几次该程序几分钟,那么完全退出该应用程序无疑具有好处。这样做的好处是,当操作系统内存不足且手机响了,并且您按下了“接听”按钮,并且等待android释放一些内存时,操作系统就不必花一周的时间退出该应用程序这样您就可以接听电话。或者,也许您收到了一封电子邮件并想阅读它-如果操作系统不首先释放它,则需要更多内存的任何应用程序都将更快地启动。 (2认同)

Bur*_*rke 10

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

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

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

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

  • 你认为什么代表"应用程序"?如果我打开Facebook应用程序,并设置新的配置文件图片 - 我的相机或图库应用程序启动.作为用户,我仍在执行相同的任务(使用Facebook).如果我然后决定关闭Facebook,我的相机和图库应用程序也必须关闭(因为它们是从Facebook推出的活动)...如果我正在编辑我的其他一些照片并且只打算关闭Facebook怎么办? ?您可能已将问题转移到潜在的数据丢失. (6认同)
  • 我认为很有趣的是,许多Android用户正在安装"高级任务杀手",这是一款关闭其他应用程序的应用程序,因为您通常无法自行完成.我一直都在使用它.退出应用程序不是我觉得你可以做的事情. (4认同)
  • 1.我认为99.99%的Android用户不应该担心操作系统如何管理幕后的应用程序.其余的都是极客,并会发现高级工具确实使系统的行为完全符合他们的要求.2.当活动暂停或停止时,您始终可以卸载任何敏感数据.3.与上面相同,可以在生命周期回调方法中释放资源.活动恢复后,可以再次分配资源. (2认同)
  • @ZsoltTörök,99.99%的人处理慢速计算机/电话,并且不得不担心操作系统如何管理幕后的应用程序. (2认同)

Pet*_*eoh 10

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

它被Android大量使用:

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


dip*_*ipu 9

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

  • Apple IOS响铃? (2认同)

Car*_*arl 9

您显然已在finish()命令中找到了所需的答案.这不会从内存中移除您的应用程序,但Android会在需要资源时执行此操作,因此您不会明确地执行此操作没有任何区别.

我只想补充一点,为了达到应用程序退出通常具有的全部效果,您可能希望将应用程序的状态重置为设备启动后首次运行时的状态.在所有活动上调用finish().这样,如果用户再次选择您的应用程序,它将显示为"新鲜",没有任何状态从模拟"退出"之前的点遗留下来.

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

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

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

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

关于system.exit(0):

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

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

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

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


小智 7

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

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

  • public void appRestart() { Intent i = new Intent(getBaseContext(), MyActivity.class); i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 开始活动(i); } (9认同)
  • 以上评论的代码确实很有效.至少你可以转到第一个活动,而不是从App完全退出.:) (2认同)

小智 7

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

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

  • 好主意.但是,即使完成活动(或服务)也不会停止操作系统.哦不,即使在执行了onDestroy之后,所有变量和东西仍然存在.我刚刚在服务中看到,即使onDestroy被调用,每个人都是一样的...... (2认同)
  • ...因此System.exit(0)帮助了=) (2认同)

StE*_*rMi 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();
Run Code Online (Sandbox Code Playgroud)

所以我保存在SharedPreferences中,我想要杀死我的应用程序,然后我开始一个Intent.请看那些旗帜; 这些将清除我的所有后台调用我的DashBoard活动,这是我的"家"活动.

所以在我的仪表板活动中,我在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();
    }
}
Run Code Online (Sandbox Code Playgroud)

它会很好用.

我唯一不理解为什么会发生这种事情的是当我做最后一次完成时(我已经检查过:它正在跟随onPause→onStop→onDestroy的所有正确流程),应用程序仍在最近的活动中(但是这是空白的).

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

我要挖掘更多,以便删除它.

  • 没有多少消费者知道操作系统是什么,更不用说如何工作,这并不会让他们变得愚蠢.想要退出/退出/关闭按钮使它们正常.当你离开房间时你关灯,更重要的是当你离开你的房子时你锁门,这就是我看不到正确退出程序的问题.让程序在后台保持活着是一个很大的安全风险. (8认同)
  • "我认为"退出按钮"是愚蠢的".大多数软件应用程序提供退出按钮. (4认同)

小智 6

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

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

我在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();
}
Run Code Online (Sandbox Code Playgroud)

这段代码可能完全错误,但它确实有效.这是我的第一个Android应用程序之一.

Voilà,一个在后台运行时不消耗CPU的应用程序,但它可以立即重新打开,因为它在RAM中(虽然不像Android生命周期那样持有RAM)...应用程序随时可用,它是一部手机,伙计们/加尔斯.如果一个应用程序耗尽了所有RAM并且无法通过操作系统关闭,那么事情可能会停止响铃= P这就是为什么操作系统需要能够在后台关闭你的应用程序(如果你的应用程序不是资源问题它不会被关闭BTW),所以让我们编写更好的应用程序.


Pra*_*dhi 6

要在任何时候关闭应用程序,请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));
}
Run Code Online (Sandbox Code Playgroud)

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

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

这将在不破坏Android生命周期的情况下运行.


Gan*_*mar 6

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

`YourActivityname.this.finish()`;
Run Code Online (Sandbox Code Playgroud)

例:

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

startActivity(intent);
MainActivity.this.finish();
Run Code Online (Sandbox Code Playgroud)

因此,不会在后台运行任何活动,当您要退出应用程序时,请使用:

MainActivity.this.finish();
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(0);
getParent().finish();
Run Code Online (Sandbox Code Playgroud)

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


Dom*_*ano 6

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

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

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

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

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


小智 6

您可能花了很多年的时间为“合适的”计算机编写“合适的”程序。你说你正在学习Android编程。这只是你必须学习的事情之一。你不能花费数年时间画水彩画并假设油画的工作原理完全相同。当我八年前编写第一个应用程序时,这对我来说是最不新鲜的概念。