小部件更新导致ANR

时间:2012-02-06 12:23:15

标签: java android widget

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

当我将小部件添加到主屏幕时,它会立即触发onUpdate,从Internet下载数据并更新小部件。这很好用。日志显示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秒内完成执行

3 个答案:

答案 0 :(得分:2)

线程是在Android上安全地进行网络访问的唯一方式。所以,是的,您需要使用类似ASyncTaskIntentService的内容。请注意,普通Service没有多大帮助,因为它在主线程上运行。

答案 1 :(得分:2)

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

答案 2 :(得分:2)

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

但是你应该做的是在应用程序不活动时执行这样的后台任务。如果您的应用程序位于前台,请仅下载数据!

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

有关更多提示,请查看通常的位置:

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