Помещение растрового изображения в пакет - PullRequest
5 голосов
/ 11 октября 2011

Я хочу передать строку и растровое изображение в службу с помощью AIDL. Служба реализует этот метод 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 Сервис создает кнопку, используя текст и значок из объекта 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), есть ли способ сохранить один аргумент 'data' в методе AIDL, чтобы сохранить текст и значок вместе?

Дополнительный вопрос: как мне решить использовать Bundles vs Parcels?

Большое спасибо.

Ответы [ 3 ]

3 голосов
/ 11 октября 2011

Вот ответ на ваш второй вопрос.

Источник: http://www.anddev.org/general-f3/bundle-vs-parcel-vs-message-t517.html

Пакет функционально эквивалентен стандартной карте.Причина, по которой мы не просто использовали карту, заключается в том, что в контексте, где используется Bundle, единственные вещи, которые допустимы для нее, это примитивы, такие как Strings, Ints и так далее.Поскольку стандартный API-интерфейс Map позволяет вставлять произвольные объекты, это позволит разработчикам помещать в карту данные, которые система на самом деле не может поддерживать, что может привести к странным, неинтуитивным ошибкам приложения.Bundle был создан, чтобы заменить Map типизированным контейнером, который ясно дает понять, что он поддерживает только примитивы.

Parcel похож на Bundle, но более сложен и может поддерживать более сложную сериализацию классов.Приложения могут реализовывать интерфейс Parcelable для определения классов приложений, которые можно передавать, особенно при использовании служб.Parcelables могут быть более сложными, чем Bundles, но это обходится значительно дороже.

Bundle и Parcel оба являются механизмами сериализации данных, и по большей части оба используются, когда код приложения передает данные через процессы,Однако из-за того, что затраты на Parcel намного выше, чем у Bundle, пакеты используются в более распространенных местах, таких как метод onCreate, где накладные расходы должны быть как можно ниже.Участки чаще всего используются, чтобы позволить приложениям определять Сервисы с помощью логических API, которые могут использовать значимые для приложения классы в качестве аргументов метода и возвращаемых значений.Если бы нам потребовался Bundle, это привело бы к действительно неуклюжим API.В целом, вы все равно должны сохранять свои API-интерфейсы служб как можно более простыми, поскольку примитивы будут сериализоваться более эффективно, чем пользовательские классы Parcelable.

2 голосов
/ 12 октября 2011

Решено.

Проблема заключалась в том, что используемый мной PNG не поддерживается Android.Код:

icon.getConfig()

возвращает ноль.

1 голос
/ 11 октября 2011

Хотя gt_ebuddy дает хороший ответ, у меня есть небольшая дополнительная заметка к вашему вопросу:

Проблема: Вы пытаетесь передать объект Bitmap в память, это может быть хорошо;однако, абсолютно нехорошо передавать много Bitmap таких объектов.Действительно плохая практика.

Мое решение: изображение уже существует в resources, оно имеет уникальный ID;использовать из этого.Вместо того, чтобы пытаться передать много тяжелых Bitmaps, вы можете передать его ID, используя Bundle или Parcel, но Bundle предпочтительнее для простой структуры данных.

...