2

应用程序后台服务更新 sqlite 数据库。因此,我的活动变得过时了。活动意图还包含过时的参数,因此 onCreate、onResume 将使应用程序崩溃。一个最简单的解决方案是重新启动整个应用程序。我不想将 IF 添加到所有活动中的所有 onCreate、onResume 方法以处理一种特殊情况。

我注意到ACRA在处理异常后执行了以下代码。

android.os.Process.killProcess(android.os.Process.myPid());
System.exit(10);

然而,许多人不鼓励使用System.exit(0). System.exit(0)Android 应用程序数据完整性真的那么危险吗?当然,我的代码会在数据库存在之前关闭数据库。

更新:

我知道如何使用finish()、内容提供者、发送广播、在 SO 上阅读许多答案等。但是,这些方法中的每一种都需要额外的数千行代码。System.exit(0)我在十分钟内实施了解决方案。重启太快了,和普通的 startActivity 动作没有区别。数据库更新/重启是在用户长时间不活动后完成的,因此应用程序已经被系统挂起。我的应用不需要实时同步。在测试期间,应用程序行为正确。这是快速而肮脏的解决方案。

因此,我询问了有关System.exit(0). 不是我如何以不同的方式进行设计。我知道目前的设计并不完美。

4

5 回答 5

2

System.exit(0)Java运行时的工件,它不适用于Android. 所以在任何情况下使用它都是最糟糕的解决方案。

为什么不优雅地使用Activity.finish()呢?

如果您终止您所在的进程,您将失去大部分缓存和重新启动时间(在用户眼中是~resume),因为下次它会更长。

阅读更多关于 Android 开发者的活动生命周期文档

于 2013-09-06T12:38:37.647 回答
1

杀死进程不会清除进程外部的任何注册资源。例如,广播接收器。这是一个泄漏,设备会告诉你很多。

您真的不应该从后台服务更新数据库模式。当您的活动恢复时执行此操作。

如果您只是在更新数据,恢复活动应该验证 Intent 指定的数据并告诉用户,例如,项目 X 是否不再存在。

于 2013-09-06T12:39:19.617 回答
0

如果仔细使用并用于特定的、经过深思熟虑的目的,任何工具都不会那么危险。

但是,就您而言,我认为这不是System.exit()正确的方法。如果您的应用程序依赖于数据库中的数据,请创建一个后台服务(或几个,取决于您的需要),它将通知您的应用程序更改并更新数据。在我看来,这是处理变化的正确方法。

至于你想使用的场景,System.exit()我个人有时会在我无法从严重错误中恢复并且不可能优雅降级时使用它。在这些情况下,最好强制停止与您的应用程序相关的所有资源,而不是让松散的东西纠缠在一起。澄清一下,在做任何激进的事情之前,您应该始终使用错误处理。正确的错误处理通常是要走的路。

但这是一个非常微妙的话题,你可能会收到很多不同的答案。

于 2013-09-06T12:38:58.627 回答
0

因此,我的活动变得过时了。

使用ContentProviderand ContentObserver(或Loader框架),或使用消息总线(LocalBroadcastManager、Otto 等)在原地更新活动。

Activity Intents 还包含过时的参数,所以 onCreate、onResume 会使应用程序崩溃

将相关的“参数”复制到活动的数据成员。根据需要更新那些数据成员(例如,从消息总线引发的事件的处理程序中)。保留该数据作为您的实例状态的一部分以进行配置更改(例如,onSaveInstanceState())。使用来自onCreate()onResume()等的数据。

最简单的解决方案是重新启动整个应用程序

如果您重视您的用户,这并不容易,因为您的用户不会欣赏您的应用程序在他们使用时自发消失。您是否认为每次收到电子邮件时 Gmail 都会崩溃他们自己的应用程序?

接下来,您将建议编写一个 Web 应用程序,该应用程序使用一些漏洞来使浏览器崩溃,因为您不知道如何更新网页。

我注意到 ACRA 在处理异常后执行了以下代码。

顶级异常处理程序大约是拥有此类代码的唯一明智的地方,即使在那里,目标也是使此代码永远不会运行(即,没有未处理的异常)。

于 2013-09-06T12:49:33.943 回答
-1

这里有一个现有的答案,可以帮助您了解为什么人们说使用 System.Exit() 不好。

于 2013-09-06T12:38:02.470 回答