所以我有一个应用程序小部件,它刷新得很好,像发条一样定期将新的位图加载到ImageView
中。 然后,在某个时候,静默地,它将停止进一步更新。 我可以从日志和我的代码正在查询的服务器上的活动看出,该小部件实际上仍在继续定期触发(通过onReceive()
捕获的广播,并按预期执行其工作。 唯一没有发生的事情是小部件内容没有更新。
因此,在小部件触发时执行的代码中,我正在创建一个新的 RemoteViews 并向其添加内容,包括通过 remoteViews.setImageViewBitmap(imageViewID, bmp)
加载新的位图,然后最终调用appWidgetManager.updateAppWidget(appWidgetId, remoteViews)
来更新小部件内容。 效果很好...直到它停止工作。
我不确定要发布什么代码,因为该代码在 99% 的时间内运行良好,但偶尔updateAppWidget()
会停止工作,没有明显的原因。 似乎这是一个系统问题,而不是我的代码中的错误,但我可能是错的。
唯一可能提示这一点的是,当连接发生变化时,例如从无信号到WiFi,也许经常发生此类变化。 在这些情况下,它似乎发生得更多。
一旦小部件冻结,唯一解冻它的事情就是重新启动设备。 如果不重新启动,即使删除小部件并添加新小部件也不起作用。 事实上,添加一个新小部件会导致一个死的小部件,它甚至不响应打开配置活动的点击,大概是因为remoteViews.setOnClickPendingIntent(R.id.widget, configPendingIntent)
就像我精心构建并发送给appWidgetManager.updateAppWidget()
RemoteViews
中的其他所有内容一样被忽略。
这似乎和这里许多其他人描述的差不多:
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/
有什么想法吗? 它慢慢地把我逼疯了!
remoteViews.setImageViewBitmap(imageViewID, bmp)
别这样。这样做会包裹位图,并将整个内容作为绑定器事务发送。活页夹用于传输少量数据,不能很好地处理位图。即使小部件不断更新,它也使用比需要更多的系统资源和更多的启动器资源(启动器必须解包位图,至少暂时存储打包的字节和未打包的字节,并且必须在 UI 线程上完成。但是您看到的问题是您链接的错误,有时大型活页夹事务会触发TransactionTooLargeException
,并且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