10

所以我有一个很好刷新的应用程序小部件,将一个新的位图加载到一个ImageView像发条一样的规则中。然后,在某个时候,它会默默地停止更新。我可以从日志和我的代码正在查询的服务器上的活动中看出,小部件实际上仍在继续定期触发(通过 捕获的广播onReceive(),并按预期执行其工作。唯一没有发生的事情是小部件内容没有更新。

因此,在小部件触发时执行的代码中,我正在创建一个新的 RemoteViews 并向其添加内容,包括通过 加载新位图remoteViews.setImageViewBitmap(imageViewID, bmp),然后最后调用appWidgetManager.updateAppWidget(appWidgetId, remoteViews)以更新小部件内容。工作得很好......直到它停止工作。

我不确定要发布什么代码,因为这件事在 99% 的时间里都可以正常工作,但偶尔会updateAppWidget()停止工作,没有明显的原因。似乎这是一个系统问题,而不是我的代码中的错误,但我可能是错的。

唯一可能提示出现这种情况的是连接发生变化时,例如从无信号变为 WiFi,可能会频繁发生此类变化。在这些情况下似乎发生得更多。

一旦小部件冻结,唯一解冻它的就是重新启动设备。如果不重新启动,即使删除小部件并添加新小部件也不起作用。事实上,添加一个新的小部件会导致一个死小部件,它甚至不响应点击打开配置活动,大概是因为像我仔细构造和发送到remoteViews.setOnClickPendingIntent(R.id.widget, configPendingIntent)的其他所有内容一样被忽略。RemoteViewsappWidgetManager.updateAppWidget()

它似乎与这里许多其他人所描述的差不多:

https://code.google.com/p/android/issues/detail?id=28216

到目前为止,似乎还没有已知的治疗方法。https://code.google.com/p/android/issues/detail?id=28216#c56上的帖子似乎提供了一些承诺,但我尝试过AppWidgetHost.startListening()在各个地方打电话,包括通过重复警报定期打电话看看我是否可以启动小部件,但似乎没有任何效果。

其他用户(而不是开发人员)似乎也看到了这个问题:http ://androidforums.com/threads/clock-widget-keeps-freezing-please-help.530333/

有任何想法吗?它正在慢慢让我发疯!

4

1 回答 1

5
remoteViews.setImageViewBitmap(imageViewID, bmp)

不要这样做。这样做会打包位图并将整个内容作为活页夹事务发送。活页夹旨在传输少量数据并且不能很好地处理位图。即使小部件不断更新,它也使用了比需要更多的系统资源,以及更多的启动器资源(启动器必须解包位图,至少临时存储已打包的字节和未打包的字节,并且必须在 UI 线程上完成. 但是您看到的问题是您链接的错误,有时大型活页夹事务会触发 aTransactionTooLargeException并且AppWidgetManagerService通过停止所有未来的更新(有时对所有小部件,有时只是对您的小部件)来错误地处理此问题。

相反,您应该使用setImageViewUri https://developer.android.com/reference/android/widget/RemoteViews.html#setImageViewUri(int,%20android.net.Uri)。这需要做更多的工作,因为您需要保存位图,然后向启动器发送一个 uri,尽管目前所有或几乎所有启动器都有READ_EXTERNAL_STORAGE一个file:///到外部存储的 uri,但您将来不应该依赖它,而是应该使用FileProvider https://developer.android.com/reference/android/support/v4/content/FileProvider.html

于 2015-05-23T06:32:46.923 回答