【问题标题】:Widget update results in ANR小部件更新导致 ANR
【发布时间】:2012-02-06 12:23:14
【问题描述】:

我有一个简单的应用程序,它可以读取互联网资源并以图像视图和文本视图的形式在小部件或列表视图活动中显示信息。 除了从 Internet 下载数据外,它还显示在 ViewFlipper 的小部件中。

当我将小部件添加到主屏幕时,它会立即触发 onUpdate,从互联网下载数据并更新小部件。这工作得很好。日志显示 onUpdatedataDownloaded 相隔约 3 秒。 在下一次更新时(手机已进入睡眠模式),更新不会发生,这是我的日志报告的内容。

  • onUpdate 被调用。
  • dataDownloading 被调用,但在最初调用 onUpdate 20 秒后。我认为这是因为手机处于睡眠状态,初始化网络套接字等需要时间。
  • 在此之后,我收到 ANR 日志条目,并且没有发生小部件更新,进程实际上已停止,小部件停留在屏幕上并且不响应活动内的手动更新,否则在未引发 ANR 异常时有效.

我正在寻找可能的解决方案。我正在考虑在不同的线程中调用所有下载(从 AppWidgetProvider 中,可能使用AsyncTask),将数据存储在 SQLite 或本地存储中并进行小部件更新(没有下载,只是从 SQLite 和本地存储读取数据) 在下一次onUpdate 通话中。这将使应用程序/小部件进程更具响应性,并且不会导致 ANR 出错。

这种线程方法是一种不好的做法吗?有替代方案吗?我应该改用服务吗?我倾向于不使用服务,除非它有很多优点。

对不起,文字墙:)

编辑:来自文档http://developer.android.com/guide/practices/design/responsiveness.html

当检测到以下情况之一时,Android 将显示特定应用程序的 ANR 对话框:

  • 在 5 秒内没有响应输入事件(例如按键、屏幕触摸)
  • BroadcastReceiver 未在 10 秒内完成执行

【问题讨论】:

    标签: java android widget


    【解决方案1】:

    线程是在 Android 上安全进行网络访问的唯一方式。所以,是的,您需要使用ASyncTaskIntentService 之类的东西。请注意,普通的 Service 不会有太大帮助,因为它在主线程上运行。

    【讨论】:

    • 谢谢,在阅读完文档后,我打算申请服务,但您与 IntentService 达成了交易。我想我必须从服务发送一个广播并在AppWidgetManager.onReceive 中捕获它,然后在那里更新可视化小部件。
    • 您也可以使用 ResultReceiver 来代替广播。
    【解决方案2】:

    如果您正在执行网络请求,那么您需要在 AsyncTaskThread/Handler 组合中执行此操作。以下是一些帮助链接:

    【讨论】:

      【解决方案3】:

      我猜使用 IntentService 和数据库后端是正确的方法。

      但您永远不应该在应用程序不活动时执行此类后台任务。请仅在您的应用处于前台时才下载数据!

      对于小部件,您应该使用“updatePeriodMillis”属性。 Android 系统确保仅在小部件可见时才执行此操作。

      更多提示请查看常用位置:

      http://developer.android.com/guide/topics/appwidgets/index.html

      【讨论】:

      • 我的小部件设置为每 30 分钟更新一次,但我在应用程序中有一个设置可以更改此设置。我默认为 3 小时。如果我不每 3 小时下载一次数据,如何进行更新?当然,如果小部件没有添加到主屏幕,则不会进行任何更新。你把我弄糊涂了。
      • 好吧,别费心了。我以为你会更频繁地更新小部件。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多