我经常看到一些帖子说,即使应用程序正在关闭(onStop),也应该在后台线程中完成文件写入,即使这项工作对应用程序至关重要。
我对此感到困惑。当然,onStop是一个ui调用,android应该,也许必须,宽容地给应用程序时间来完成关键工作。
我担心在后台线程上执行关键工作,不会通知操作系统该工作是关键的,需要完成。
这有几个相关方面:
——什么困扰着我;我写这个问题的原因---
允许onStop返回后,在后台线程上执行关键工作是否可靠?onStop的返回是否向android发出了一个信号,即应用程序已经完成了关键的任务,并且即使android立即终止了该应用程序,该应用程序在恢复时也将正常运行?
(换言之,在我看来,[在后台线程中做那个关键工作]的建议是错误的。我正试着寻找证据。这就是我写这个问题的原因。)
——是否有任何支持背景法的证据?-----
有证据表明,如果我听从建议,在后台线程中工作,android在决定是否可以终止应用程序时,会考虑运行线程的存在。[如果我在写一个移动操作系统,我不会给背景线程的存在太大的份量。我怀疑大多数复杂的应用程序仍在运行后台线程。]
有证据表明,将onStop的返回延迟200毫秒是不好的。
——或者有任何证据表明在未来这样做是可以的?-----
或者相反,在ui线程中直接执行的证据在某个合理的时间内是可以的,以及关于什么时间可能被认为是合理的证据。
——或者大型应用程序编写器是做什么的?-----
关于高下载率、高知名度应用程序使用哪种方法的证据。在桌面上写文件时,它们是停留在ui线程上,还是在后台?或者他们使用服务来百分之百确定?[我认为,除非绝对必要,否则Android不太可能以一种会让这些人崩溃的方式被改变。]
注:我看过很多意见。我不需要再听别人的意见了。寻找证据。
注意:我不想听到关于创建android将继续运行的服务或其他解决方案的建议。我说的工作不够长,不足以证明这一点。我指的是每一个重要的应用程序在接到终止通知时所做的园艺多样性工作。
最新消息:我很欣赏这两份回复中的信息,但我觉得有一点被忽视了:
onStop和所有其他ui回调之间有一个关键的区别:
当应用程序从onstop返回时,返回的行为是应用程序向操作系统发出的声明,即应用程序现在可以安全地被终止。正确的?这不是OnStop的精髓吗?
因此,从逻辑上讲,应用程序在完成所有关键工作之前不应该从onstop返回。
(是的,显然应该设计应用程序,以便能够尽快完成关键工作。)但不要失去重点。如果你回来,你告诉操作系统它现在可以安全地杀死你。如果它真的立即杀死你,而你的应用程序状态是混乱的,因为你在一个未完成的后台线程上工作,那么你的方法是有缺陷的。不是吗?我想看看我的分析有什么问题……)
更新第2号
在与@commonware的讨论中(见他回答下的注释),我了解到intentservice实现了我想要的,并且不需要向用户请求任何额外的权限。
我在想ios,它对后台工作非常严格。我相信任何这样的计划都需要在ios下获得额外的应用许可。我避免额外的应用程序权限,以免吓跑任何用户。
因此,作为一个经验丰富的iOS应用程序开发人员,但经验不足的Android开发人员,我不知道我需要的答案是:
与ios不同,IntentService可以在不添加另一个应用程序权限的情况下,使用background work来执行操作系统将继续执行的操作,即使在应用程序的活动已终止之后。
由于intentservice将继续运行,而且启动成本不高,也不需要额外的应用程序许可,因此使用intentservice启动后台工作没有“负面影响”,允许onstop在确保完成关键工作的同时迅速返回。
我接受了Commonware的回答。
根据@zgc7009的问题在评论中更新3,以及我的回复评论,我还应该确保所有关键信息始终被持久存储。请参阅这些评论,以获取在顶部之前未存储的内容的详细信息,这导致我发布此问题。这种不断更新的方法的优点是,即使应用程序崩溃,它也会有帮助。
注意:即使应用程序正在退出,用于保存关键信息的机制也必须保证完成(对于可靠性而言)。[或至少是“交易担保”,保证数据不会被中途更改。]
我可能会使用intentservice来实现这一点。(我们的数据是序列化的XML,因此我们的代码需要运行,直到它完成对关键数据的序列化,并刷新并关闭该本地文件。)

最佳答案

即使应用程序正在关闭(onstop)
onStop()Activity上的一种方法。当活动不再可见时将调用它。这可能与应用程序是否正在“关闭”有关。例如,从一个活动转换到另一个活动会触发onStop(),配置更改也是如此(默认情况下)。
当然,onstop是一个ui调用,android应该,也许必须,宽容地给应用程序时间来完成关键工作。
这不是“宽大处理”的问题。onStop()在主应用程序线程上调用。在主应用程序线程上执行的任何操作都会绑定该线程,从而阻止android在该线程上执行其他操作。由于ui是由主应用程序线程驱动的,因此在您在onStop()中绑定主应用程序线程的这段时间内,ui将被冻结。
请注意,这不是onStop()所独有的。连接主应用程序线程的任何地方都是冻结ui的地方。android开发人员采用了“jank”一词来专门表示这种行为。
你可能会觉得200米的冷冻用户界面是完全可以接受的。其他开发商可能不会。用户可以也可以不。
但这有关系吗,在上台的时候?在暂停的时候那会很糟糕,但是在停止的时候呢?
在很多情况下,确实如此。仅仅因为onStop()活动不再在前台并不意味着您的任何活动都不在前台,除非您只有一个活动,而且这不是配置更改。
在决定是否可以终止应用程序时,android会考虑运行线程的存在。
它不会,除非该线程由Service管理(在这种情况下,android将Service考虑在内,而不是线程)。
为了扭转局面,我非常感兴趣的是,有任何证据表明android将在被调用后~200毫秒内终止进程。否则,您的线程将运行到完成而不会出现问题。
我特别感兴趣的是,我所看到的文档在讨论onstop的不同性质时失败了。
这是因为在其他人看来,onStop()没有什么不同。欢迎你相信这是不同的,但请不要期望其他人“重新控制”已经写了什么Android应用程序开发调整到您的世界观。
有证据表明,将从顶部返回的时间延迟200毫秒是不好的。
“坏”是一种主观描述。可以说:
onStop()在主应用程序线程上调用(要证明这一点,请记录线程ID)
绑定主应用程序线程可防止在该线程上执行其他工作(线程操作的基础)
Android aims to update the UI on a 60fps basis或~16ms/帧
约200毫秒为约12帧,每秒60帧(长分区)
当应用程序从onstop返回时,返回的行为是应用程序向操作系统发出的声明,即应用程序现在可以安全地被终止。
“app”不会从onStop()返回。onStop()onStop()上的一种方法。一个应用程序可能有零个、一个或多个活动。Activity与移动到后台的应用程序松散相关,但在其他情况下也会调用onStop(),如前面在这个答案中所述。
如果你回来,你告诉操作系统它现在可以安全地杀死你
您假设如果未能从onStop()返回,您的进程将永远保持活力。onStop()是一个咨询活动,告诉你“嘿,你的活动已经转移到后台了”。对于负责终止进程以释放系统ram的os进程来说,从onStop()返回的速度有多快并不重要。

关于android - 在Android onStop上执行〜200毫秒工作的最可靠方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39640673/

10-08 23:34