1

以下 3 种方法(来自RemoteViews类)可用于在 Android 上更新主屏幕小部件上的图像:

setImageViewResource (int viewId, int srcId)
setImageViewUri (int viewId, Uri uri)
setImageViewBitmap (int viewId, Bitmap bitmap)

但经过大量研究,我发现这setImageViewUri()是最好的使用,以避免"**!!! FAILED BINDER TRANSACTION !!!**"更新小部件时可能发生的错误。但为什么会这样呢?我找不到任何适当的理由或 JavaDoc 文档。

4

2 回答 2

2

Binder 事务因太大而失败。在远程过程调用期间,调用的参数和返回值作为存储在 Binder 事务缓冲区中的 Parcel 对象进行传输。如果参数或返回值太大而无法放入事务缓冲区,则调用将失败并抛出 TransactionTooLargeException。Binder 事务缓冲区有一个有限的固定大小,目前为 1Mb,由进程正在进行的所有事务共享。因此,当有许多事务正在进行时,即使大多数单个事务的大小适中,也可能会引发此异常。当远程过程调用引发 TransactionTooLargeException 时,有两种可能的结果。客户端无法将其请求发送到服务(很可能是因为参数太大而无法放入事务缓冲区),或者服务无法将其响应发送回客户端(很可能如果返回值是太大而无法放入事务缓冲区)。无法判断这些结果中的哪些实际发生了。客户端应该假设发生了部分故障。避免 TransactionTooLargeException 的关键是保持所有事务相对较小。尽量减少为参数和远程过程调用的返回值创建 Parcel 所需的内存量。避免传输大量字符串或大型位图。如果可能的话,试着把大的请求分解成更小的部分。如果您正在实施一项服务,它可能有助于对客户端可以执行的查询施加大小或复杂性约束。例如,如果结果集可能会变大,则不允许客户端一次请求多于几条记录。或者,不要一次返回所有可用数据,而是先返回基本信息,然后让客户根据需要要求提供更多信息。

如果您真的想这样做,这是可能的,但它会消耗大量内存并且速度也很慢。如果您的手机较旧且位图较大,则可能无法使用。您可以将其作为额外的传递,例如intent.putExtra("data", bitmap). A Bitmap implements Parcelable, 所以你可以把它放在一个额外的并使用setImageViewBitmap (int viewId, Bitmap bitmap).

如果你想在活动之间传递它,我会将它存储在一个文件中。这样效率更高,工作量也更少。您可以使用MODE_PRIVATE任何其他应用程序无法访问的数据文件夹中创建私有文件。

如果你将它作为 Parcelable 传递,你一定会得到一个 JAVA BINDER FAILURE 错误。因此,解决方案是这样的:如果位图很小,例如缩略图,则将其作为字节数组传递并构建位图以在下一个活动中显示。例如:

在您的通话活动中...

Intent i = new Intent(this, NextActivity.class);
Bitmap b; // your bitmap
ByteArrayOutputStream bs = new ByteArrayOutputStream();
b.compress(Bitmap.CompressFormat.PNG, 50, bs);
i.putExtra("byteArray", bs.toByteArray());
startActivity(i);

...在您的接收活动中

if(getIntent().hasExtra("byteArray")) {
    ImageView previewThumbnail = new ImageView(this);
    Bitmap b = BitmapFactory.decodeByteArray(
      getIntent().getByteArrayExtra("byteArray"),0,getIntent().getByteArrayExtra("byteArray").length);        
previewThumbnail.setImageBitmap(b);
}
于 2013-09-17T05:04:33.477 回答
1

有些人建议使用 setImageViewUri() 来降低冻结主屏幕上的小部件的风险。见https://code.google.com/p/android/issues/detail?id=28216#c102

于 2013-12-08T22:18:56.360 回答