开发者

Putting a Bitmap into a Bundle

开发者 https://www.devze.com 2023-04-12 19:01 出处:网络
I want to pass a String and a Bitmap to a Service using AIDL. The Service implements this AIDL method:

I want to pass a String and a Bitmap to a Service using AIDL. The Service implements this AIDL method:

void addButton(in Bundle data);

In my case, the Bundle contains a String and a Bitmap.

The calling application (client) has this code:

...
// 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();
}
...

On the service end, I have a ButtonComponent class with this code:

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.ge开发者_StackOverflowtParcelable("BundleIcon");
        return icon;
    }

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

    public int describeContents() {
        return 0;
    }
}

After creating a ButtonComponent, the Service creates a button using the text and icon from the ButtonComponent object:

...
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);
}
...

As a result, the button is displayed with the correct text and I can see the space for the icon, but the actual bitmap is not drawn (i.e. there's an empty space on the left side of the text).

Is it correct to put a Bitmap into a Bundle in this way?

If I should use a Parcel (vs a Bundle) is there any way to maintain a single 'data' argument in the AIDL method to keep text and icon together?

Side question: How do I decide to use Bundles vs Parcels?

Many thanks.


Here is answer for your second question.

Source : 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.


Solved.

Problem was that the PNG I was using is not supported by Android. The code:

icon.getConfig()

returns null.


While gt_ebuddy gives a nice answer, I just have a little side note to your question:

Problem: You are trying to pass a Bitmap object to memory, it can be fine; however, it's absolutely not good to pass many Bitmap objects like this. Really bad practice.

My Solution: The image is already existed in resources, it has an unique ID; make use out of it. Instead of trying to pass a lot of heavy Bitmaps, you can pass its ID using Bundle or Parcel, but Bundle is preferable for simple data structure.

0

精彩评论

暂无评论...
验证码 换一张
取 消