5

我想使用 AIDL 将字符串和位图传递给服务。Service 实现了这个 AIDL 方法:

void addButton(in Bundle data);

在我的例子中,Bundle 包含一个字符串和一个位图。

调用应用程序(客户端)具有以下代码:

...
// Add text to the bundle
Bundle data = new Bundle();
String text = "Some text";
data.putString("BundleText", text);

// Add bitmap to the bundle
Bitmap icon = BitmapFactory.decodeResource(getResources(), R.drawable.myIcon);
data.putParcelable("BundleIcon", icon);

try {
    myService.addButton(data);

} catch (RemoteException e) {
    Log.e(TAG, "Exception: ", e);
    e.printStackTrace();
}
...

在服务端,我有一个带有以下代码的 ButtonComponent 类:

public final class ButtonComponent implements Parcelable {
    private final Bundle mData;

    private ComponComponent(Parcel source) {
        mData = source.readBundle();
    }

    public String getText() {
        return mData.getString("BundleText");
    }

    public Bitmap getIcon() {
        Bitmap icon = (Bitmap) mData.getParcelable("BundleIcon");
        return icon;
    }

    public void writeToParcel(Parcel aOutParcel, int aFlags) {
        aOutParcel.writeBundle(mData);
    }

    public int describeContents() {
        return 0;
    }
}

创建 ButtonComponent 后,Service 使用 ButtonComponent 对象中的文本和图标创建一个按钮:

...
mInflater.inflate(R.layout.my_button, aParent, true);
Button button = (Button) aParent.getChildAt(aParent.getChildCount() - 1);

// Set caption and icon
String caption = buttonComponent.getText();
if (caption != null) {
    button.setText(caption);
}

Bitmap icon = buttonComponent.getIcon();
if (icon != null) {
    BitmapDrawable iconDrawable = new BitmapDrawable(icon);
    button.setCompoundDrawablesWithIntrinsicBounds(iconDrawable, null, null, null);
}
...

结果,按钮以正确的文本显示,我可以看到图标的空间,但未绘制实际的位图(即文本左侧有一个空白区域)。

以这种方式将 Bitmap 放入 Bundle 是否正确?

如果我应该使用 Parcel(与 Bundle 相比),有没有办法在 AIDL 方法中维护单个“数据”参数以将文本和图标保持在一起?

附带问题:我如何决定使用捆绑包和包裹?

非常感谢。

4

3 回答 3

3

这是您第二个问题的答案。

来源:http ://www.anddev.org/general-f3/bundle-vs-parcel-vs-message-t517.html

Bundle 在功能上等同于标准 Map。我们不只是使用 Map 的原因是因为在使用 Bundle 的上下文中,唯一合法放入其中的东西是诸如字符串、整数等原语。因为标准 Map API 允许您插入任意对象,这将允许开发人员将系统实际上无法支持的数据放入 Map,这将导致奇怪的、非直观的应用程序错误。创建 Bundle 是为了将 Map 替换为类型安全的容器,明确表明它只支持原语。

Parcel 类似于 Bundle,但更复杂,可以支持更复杂的类序列化。应用程序可以实现 Parcelable 接口来定义可以传递的特定于应用程序的类,尤其是在使用服务时。Parcelables 可以比 Bundles 更复杂,但这是以显着更高的开销为代价的。

Bundle 和 Parcel 都是数据序列化机制,并且在大多数情况下,两者都用于应用程序代码跨进程传递数据时。但是,由于 Parcel 的开销比 Bundle 高得多,因此 Bundles 用于更常见的地方,例如 onCreate 方法,其中开销必须尽可能低。Parcels 最常用于允许应用程序使用逻辑 API 定义服务,这些 API 可以使用对应用程序有意义的类作为方法参数和返回值。如果我们在那里需要 Bundle,这将导致非常笨重的 API。通常,您仍应使您的服务 API 尽可能简单,因为原语将比自定义 Parcelable 类更有效地序列化。

于 2011-10-11T14:56:31.397 回答
2

解决了。

问题是我使用的 PNG 不受 Android 支持。编码:

icon.getConfig()

返回空值。

于 2011-10-12T16:36:31.737 回答
1

虽然 gt_ebuddy 给出了一个很好的答案,但我对你的问题有一点旁注:

问题:您正在尝试将Bitmap对象传递到内存,这很好;Bitmap但是,像这样传递很多对象是绝对不好的。真是不好的做法。

我的解决方案:图像已经存在于 中resources,它具有唯一性ID;充分利用它。Bitmaps您可以ID使用Bundleor来传递它,而不是尝试传递大量繁重的Parcel,但Bundle对于简单的数据结构来说更可取。

于 2011-10-11T16:33:00.200 回答