android – 将位图放入Bundle

我想使用AIDL将String和Bitmap传递给服务.服务实现此AIDL方法:

void addButton(in Bundle data);

在我的例子中,Bundle包含一个String和一个Bitmap.

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

...
// 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后,服务使用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(vs一个Bundle)有没有办法在AIDL方法中维护一个’data’参数来保持文本和图标在一起?

附带问题:我如何决定使用Bundles vs Parcels?

非常感谢.

解决方法:

这是你的第二个问题的答案.

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

A Bundle is functionally equivalent to a standard Map. The reason we
didn’t just use a Map is because in the contexts where Bundle is used,
the only things that are legal to put into it are primitives like
Strings, ints, and so on. Because the standard Map API lets you insert
arbitrary Objects, this would allow developers to put data into the
Map that the system can’t actually support, which would lead to weird,
non-intuitive application errors. Bundle was created to replace Map
with a typesafe container that makes it explicitly clear that it only
supports primitives.

A Parcel is similar to a Bundle, but is more sophisticated and can
support more complex serialization of classes. Applications can
implement the Parcelable interface to define application-specific
classes that can be passed around, particularly when using Services.
Parcelables can be more sophisticated than Bundles, but this comes at
a cost of significantly higher overhead.

Bundle and Parcel are both data serialization mechanisms, and for the
most part both are used when application code is passing data across
processes. However, because Parcel is much higher overhead that
Bundle, Bundles are used in the more common places like the onCreate
method, where overhead must be as low as possible. Parcels are most
commonly used to allow applications to define Services with logical
APIs that can use application-meaningful classes as method arguments
and return values. If we required Bundle there, it would result in
really clunky APIs. You should in general still keep your Service APIs
as simple as possible, because primitives will serialize more
efficiently than custom Parcelable classes.

上一篇:Android监听器序列化


下一篇:android – ParcelFileDescritor.createPipe(),又名pipe(2)和安全性