Передача перечислений через вспомогательные интерфейсы - PullRequest
5 голосов
/ 08 февраля 2011

Поскольку перечисления не являются примитивными типами, какой самый эффективный способ передать перечисление через интерфейс aidl в Android?Есть ли способ преобразовать перечисление в порядковый номер первым?

Ответы [ 3 ]

8 голосов
/ 21 мая 2012

Я просто использую

String enumString = myEnum.name() 

(с MyEnum в качестве enum и myEnum в качестве значения), чтобы получить представление String, а затем

MyEnum myEnum = MyEnum.valueOf(enumString) 

, чтобы восстановить перечисление из представления String.

Использование Ordinals может быть немного быстрее, но если я смогу добавить Enums позже, это с большей вероятностью сломает старый код.

// Edit: поскольку мне не нравится иметь Stringв качестве возвращаемого типа я теперь реализовал Parcellable, как упомянуто здесь: Передача enum или объекта через намерение (лучшее решение)

import android.os.Parcel;import android.os.Parcelable;

enum InitResponse implements Parcelable {
// Everything is fine.
SUCCESS,
// Something else
FOO;


@Override
public int describeContents() {
    return 0;
}

@Override
public void writeToParcel(final Parcel dest, final int flags) {
    dest.writeString(name());
}

public static final Creator<InitResponse> CREATOR = new Creator<InitResponse>() {
    @Override
    public InitResponse createFromParcel(final Parcel source) {
        return InitResponse.valueOf(source.readString());
    }

    @Override
    public InitResponse[] newArray(final int size) {
        return new InitResponse[size];
    }
};

}
5 голосов
/ 08 февраля 2011

Не примитивные типы, кроме String, требуют указателя направления.Индикаторы направления включают in, out и inout.

. Для этого ознакомьтесь с официальной документацией: http://developer.android.com/guide/developing/tools/aidl.html#aidlsyntax

Также вы можетерассмотрите возможность передачи String или порядкового представления перечисления и переведите его обратно при необходимости.Это взято из Effective Java 2nd edition:

// Implementing a fromString method on an enum type
private static final Map<String, Operation> stringToEnum = new HashMap<String, Operation>();
static { // Initialize map from constant name to enum constant
    for (Operation op : values())
        stringToEnum.put(op.toString(), op);
} // Returns Operation for string, or null if string is invalid
public static Operation fromString(String symbol) {
    return stringToEnum.get(symbol);
}

В приведенном выше случае Operation является enum.


Чтобы получить порядковый номер перечисления, рассмотритеэтот пример:

public enum Badges{
    GOLD, SILVER, BRONZE;
}

// somewhere else:
int ordinal = Badges.SILVER.ordinal();// this should be 1
0 голосов
/ 21 апреля 2019

Да, вы можете передавать перечисления через AIDL, но вам нужно реализовать Parcelable для типа перечисления.

1: реализация Parcelable.

public enum RepeatMode implements Parcelable {
    NoRepeat,
    RepeatAll,
    RepeatTrack,
    ;

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(toInteger());
    }

    @Override
    public int describeContents() {
        return 0;
    }

    public static final Creator<RepeatMode> CREATOR = new Creator<RepeatMode>() {
        @Override
        public RepeatMode createFromParcel(Parcel in) {
            return RepeatMode.fromInteger(in.readInt());
        }

        @Override
        public RepeatMode[] newArray(int size) {
            return new RepeatMode[size];
        }
    };

    public int toInteger() { return this.ordinal(); }
    public static RepeatMode fromInteger(int value)
    {
        return values()[value];
    }
}
  1. Импорт:

    RepeatMode.aidl: пакет com.cyberdyne.media;

    Parcelable RepeatMode;

  2. И не забудьте пометить аргументы перечисления как аргументы.

Вид очевидного, когда вы думаете об этом. Но держу пари, что Google не использует много перечислений в интерфейсах IBinder. Я делаю это все же. (Спасибо студии Android за предоставление "Implement Parcelable", который не работает полностью для перечислений, но делает вещи относительно простыми).

Дискурс по Android перечислениям:

Рекомендации по лучшей практике для перечислений в Android были сняты много месяцев назад. Вы торгуете около 200 байтов исполняемого файла для ужасного ужасного кода. Телефоны прошли долгий путь со времен Android 1.0. Это легко. Используйте перечисления. (Или используйте безумную управляемую Kotlin систему атрибутов, которую использует Google. Удачи в этом.)

Официальные знания Java, восходящие к оригинальной спецификации языка Java, не поощряют использование обнаженного ординала (). Рассуждение: сопровождающие в глубоком будущем могут невольно переупорядочить порядковые номера и разбить вещи. Честно говоря, я думаю, что это напыщенное явление Java. Я долго боролся с этим, и после долгих поисков души я сдался.

public enum Badges {
   GOLD,SILVER, BRONZE; // Must match @array/badge_states 

   public int toInteger() { return this.ordinal(); }
   public static Badges fromInteger(int value) { return values()[value]);
}

Если ничего другого, он помечает класс как класс, который, вероятно, содержит целые числа. И комментарий никогда не ранит, и это делает получаемый конец маршаллированных перечислений немного красивее (и чуть чуть безопаснее).

...