Поскольку перечисления не являются примитивными типами, каков наиболее эффективный способ передать перечисление через вспомогательный интерфейс в Android? Есть ли способ сначала преобразовать перечисление в порядковый?
Передача перечислений через вспомогательные интерфейсы
Ответы (3)
Я просто использую
String enumString = myEnum.name()
(с MyEnum в качестве перечисления и myEnum в качестве значения), чтобы получить представление String, а затем
MyEnum myEnum = MyEnum.valueOf(enumString)
для восстановления перечисления из строкового представления.
Использование Ordinals может быть немного быстрее, но если я могу добавить Enums позже, это с большей вероятностью сломает старый код.
// Изменить: поскольку мне не нравится, когда тип возвращаемого значения String, я реализовал Parcellable, как указано здесь: Передача перечисления или объекта через намерение (лучшее решение)
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];
}
};
}
Непримитивные типы, кроме
String, требуют указателя направления. Указатели направления включаютin,outиinout.
Взгляните на официальную документацию для этого: http://developer.android.com/guide/developing/tools/aidl.html#aidlsyntax.
Кроме того, вы можете рассмотреть возможность передачи строкового или порядкового представления перечисления и при необходимости перевести его обратно. Это взято из 2-го издания Effective Java:
// 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
Да, вы можете передавать перечисления через 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];
}
}
Импорт:
RepeatMode.aidl: пакет com.cyberdyne.media;
parcelable RepeatMode;
И не забудьте пометить аргументы перечисления как аргументы.
Кажется очевидным, если подумать. Но я уверен, что Google не использует много перечислений в интерфейсах IBinder. Хотя я это делаю. (Спасибо студии Android за предоставление «Реализовать 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]);
}
По крайней мере, он отмечает класс как тот, который, вероятно, сохраняет целые числа. И комментарий никогда не повредит, и он делает приемную часть упорядоченных перечислений немного красивее (и чуть-чуть безопаснее).
javacперед обработкой байт-кода. В любом случае ... Я люблю перечисления и использую их, когда они делают вещи ясными и элегантными. - person Cristian   schedule 09.08.2013