IntentService 中的数据库操作导致应用程序停止,变得无响应并给出 ANR

Posted

技术标签:

【中文标题】IntentService 中的数据库操作导致应用程序停止,变得无响应并给出 ANR【英文标题】:Database operations in IntentService results into application halt,become unresponsive and giving ANR 【发布时间】:2016-10-22 19:35:56 【问题描述】:

我在警报管理器中使用 IntentService 每 15 秒触发一次。 我必须不断地向服务器发送大量数据并在后台接收大量数据作为响应。 我必须遵循以下流程:

    我正在通过查询从数据库中读取数据。

    然后通过POJO架构转换成Json。

    使用 Retrofit 库将此 JSON 请求发送到服务器。

    接收数据作为响应。

    如果数据库中有任何更新,则通过某些查询将此数据插入我的数据库。

还有其他方法吗?当我面临 ANR 时。 如果数据较少,则工作正常。但随着数据量变大,UI 会停止并且应用程序变得无响应。

【问题讨论】:

【参考方案1】:

经过一番努力,终于找到了解决办法:

我只是使用单独的流程来为意图服务工作。

在“Manifest”文件中使用它

 <service android:name=".BackgroundSyncDataService"
        android:process=":my_process">
  </service>

说明:

名称前面的冒号前缀告诉 Android,Service 对其声明的应用程序是私有的。如果不使用冒号,Service 将是一个全局进程,可以被其他 Android 应用程序使用。

在自己的进程中运行一个服务,给它自己的内存地址空间,这个进程中虚拟机的垃圾回收器不会影响应用进程。

在自己的进程中运行服务不会阻塞应用程序,以防服务在其主线程中执行长时间运行的操作。

【讨论】:

【参考方案2】:

为避免 ANR,在使用 IntentService 时需要记住几个关键点:

不要在 onCreate 或 onStartCommand 中做大量工作 - 两者仍然是 UI 线程 不要在 ResultReceiver 中做密集的工作 不要在服务中启动您自己的线程 - 它自己已经这样做了 在 onHandleIntent 中完成您的密集工作 设计您的架构,以便您收到的唯一数据是已更改的数据 不要避免转移到另一个进程 - 因为这会产生 CPU 和内存开销(对您的用户不利)

另一种解决方案是切换到其他类型的 Service 并启动 HandlerThread(或者只是从后台线程启动服务本身 - 因为 Service 在启动它的线程上运行)

【讨论】:

以上是关于IntentService 中的数据库操作导致应用程序停止,变得无响应并给出 ANR的主要内容,如果未能解决你的问题,请参考以下文章

Android 地理围栏未触发、导致 GPS 活动或调用 IntentService

什么时候用IntentService

muzei - 致命异常:IntentService [TaskQueueService]

IntentService的使用

Service可以执行耗时操作吗

IntentService与Service的区别