更新大量小部件位图时避免“FAILED BINDER TRANSACTION”错误

9
我在更新我的AppWidget中的RemoteViews时遇到了一个错误。
.. !!! FAILED BINDER TRANSACTION !!!
这是因为对RemoteViews的所有更改都是串行化的(例如setInt和setImageViewBitmap)。位图也被序列化到内部捆绑包中。不幸的是,这个捆绑包有非常小的大小限制。
我不能使用setImageResource,因为我希望允许用户下载小部件的外观。
有人能推荐一种解决此问题的方法吗?我已经为每个小部件实例使用了“新”的RemoteViews对象,但单个实例包含太多更新。
谢谢!
4个回答

10

我发现的最佳解决方法是在ImageView对象上使用setImageURI

remoteViews.setUri(R.id.myImageView, "setImageURI", "file://blahblahblah.png");

以下是来自Android 开发者社区的完整讨论。


7
您可以通过以下方式缩小图像尺寸来解决此问题:
public static Bitmap scaleDownBitmap(Bitmap photo, int newHeight, Context context) {

final float densityMultiplier = context.getResources().getDisplayMetrics().density;        

int h= (int) (newHeight*densityMultiplier);
int w= (int) (h * photo.getWidth()/((double) photo.getHeight()));

photo=Bitmap.createScaledBitmap(photo, w, h, true);

return photo;
}

选择新高度,使其足够小(对于每个应该在屏幕上显示的矩形,约为100),并将其用于您的小部件,这样您的问题就会得到解决 :)

这个对我有用:Bitmap new_bitmap = scaleDownBitmap(bitmap, 180, context); remoteViews.setImageViewBitmap(R.id.chart_imageView, new_bitmap); - Hubert

1
Binder 事务缓冲区具有固定的有限大小,目前为1Mb,该大小由进程中所有正在进行的事务共享。因此,即使大多数单个事务的大小适中,当有许多事务正在进行时,仍可能抛出此异常。
请参考link

0

我尝试了上面和其他地方列出的文件URI方法。它起作用了,但有两个缺点,首先它需要500毫秒来写入文件,在我的应用程序中是明显可见的。其次,ImageView通过density()(在Nexus S上为1.5)对图像进行了缩小。

对我而言效果更好的解决方案是将图像切片并分别更新每个切片。布局看起来像这样:

<LinearLayout orientation=vertical ...>
    <ImageView id = slice1, ,,,>
    ...
    <ImageView id = slice4, ,,,>
</LinearLayout>

在小部件提供程序中,将位图切成4个片段,并分别更新每个片段(每个片段都有自己的RemoteViews和自己的appWidgetManager.updateAppWidget(...))。对于这种高级描述,我很抱歉,但希望您能理解。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接