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

Posted

技术标签:

【中文标题】更新大量小部件位图时避免 FAILED BINDER TRANSACTION 错误【英文标题】:Avoiding FAILED BINDER TRANSACTION error when updating lots of widget bitmaps 【发布时间】:2011-10-17 12:03:20 【问题描述】:

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

.. !!! Binder 交易失败!!!

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

我无法使用 setImageResource,因为我希望允许用户下载小部件的皮肤。

谁能推荐一个解决这个问题的方法?我已经为小部件的每个实例使用了一个“新”RemoteViews 对象,但是单个实例包含太多更新。

谢谢!

【问题讨论】:

【参考方案1】:

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

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

这是来自android Developers group的完整讨论

【讨论】:

【参考方案2】:

您可以通过这种方式缩小图像大小来解决它:

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)并将它用于您的小部件,您的问题将得到解决:)

【讨论】:

这个为我工作了:位图 new_bitmap = scaleDownBitmap(bitmap, 180, context); remoteViews.setImageViewBitmap(R.id.chart_imageView, new_bitmap);【参考方案3】:

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

参考这个link

【讨论】:

【参考方案4】:

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

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

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

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

【讨论】:

以上是关于更新大量小部件位图时避免 FAILED BINDER TRANSACTION 错误的主要内容,如果未能解决你的问题,请参考以下文章

将位图动态放入小部件时失败的活页夹事务

Android Widget 膨胀布局性能和内存

Android:将位图从本地存储加载到应用小部件(RemoteViews)

android小部件中的绑定器事务失败[重复]

Android 小部件位图大小

Qt 如何从 QVector 中的数据创建位图并将其显示在小部件上?