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

时间:2011-08-01 14:14:13

标签: android android-widget widget android-appwidget

我在AppWidget中更新RemoteView时遇到错误。

  

.. !!!失败的粘合剂交易!!!

这是因为对RemoteViews的所有更改都是序列化的(例如setInt和setImageViewBitmap)。位图也被序列化为内部包。不幸的是,这个捆绑包的尺寸限制非常小。

我不能使用setImageResource,因为我希望允许用户下载小部件的外观。

有人可以为此问题推荐解决方法吗?我已经为窗口小部件的每个实例使用了一个“新的”RemoteViews对象,但是单个实例包含太多更新。

谢谢!

4 个答案:

答案 0 :(得分:10)

我找到的最佳解决方法是使用setImageURI对象使用ImageView

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

以下是Android Developers group

的完整讨论

答案 1 :(得分: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;
}

选择newHeight足够小(屏幕上应该占用的每个方格约为100)并将其用于您的小部件,您的问题将得到解决:)

答案 2 :(得分:1)

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

参考此link

答案 3 :(得分:0)

我尝试了上面列出的文件URI方法和其他地方。它有效,但有两个缺点,首先需要500毫秒来编写我的应用程序中明显的文件。其次,ImageView通过密度()(Nexus S上的1.​​5)缩小图像。

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

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

然后在窗口小部件提供程序中将位图剪切成4个切片,并分别更新每个切片(每个切片都在RemoteViews和它自己的appWidgetManager.updateAppWidget(...)上。抱歉高级描述但希望你明白了