Đây là một câu hỏi cũ, nhưng mọi người đều không đề cập đến việc Enums thực sự Serializable
và do đó hoàn toàn có thể được thêm vào Ý định như một phần phụ. Như thế này:
public enum AwesomeEnum {
SOMETHING, OTHER;
}
intent.putExtra("AwesomeEnum", AwesomeEnum.SOMETHING);
AwesomeEnum result = (AwesomeEnum) intent.getSerializableExtra("AwesomeEnum");
Đề xuất sử dụng các biến tĩnh hoặc toàn ứng dụng là một ý tưởng thực sự tồi tệ. Điều này thực sự kết hợp các hoạt động của bạn với một hệ thống quản lý nhà nước và rất khó để duy trì, gỡ lỗi và ràng buộc vấn đề.
THAY ĐỔI:
Một điểm tốt đã được chú ý bởi tedzyc về thực tế là giải pháp do Oderik cung cấp cho bạn một lỗi. Tuy nhiên, sự thay thế được cung cấp là một chút rườm rà để sử dụng (thậm chí sử dụng thuốc generic).
Nếu bạn thực sự lo lắng về hiệu suất của việc thêm enum vào Intent, tôi đề xuất các phương án thay thế:
LỰA CHỌN 1:
public enum AwesomeEnum {
SOMETHING, OTHER;
private static final String name = AwesomeEnum.class.getName();
public void attachTo(Intent intent) {
intent.putExtra(name, ordinal());
}
public static AwesomeEnum detachFrom(Intent intent) {
if(!intent.hasExtra(name)) throw new IllegalStateException();
return values()[intent.getIntExtra(name, -1)];
}
}
Sử dụng:
// Sender usage
AwesomeEnum.SOMETHING.attachTo(intent);
// Receiver usage
AwesomeEnum result = AwesomeEnum.detachFrom(intent);
TÙY CHỌN 2:
(chung chung, có thể tái sử dụng và tách rời khỏi enum)
public final class EnumUtil {
public static class Serializer<T extends Enum<T>> extends Deserializer<T> {
private T victim;
@SuppressWarnings("unchecked")
public Serializer(T victim) {
super((Class<T>) victim.getClass());
this.victim = victim;
}
public void to(Intent intent) {
intent.putExtra(name, victim.ordinal());
}
}
public static class Deserializer<T extends Enum<T>> {
protected Class<T> victimType;
protected String name;
public Deserializer(Class<T> victimType) {
this.victimType = victimType;
this.name = victimType.getName();
}
public T from(Intent intent) {
if (!intent.hasExtra(name)) throw new IllegalStateException();
return victimType.getEnumConstants()[intent.getIntExtra(name, -1)];
}
}
public static <T extends Enum<T>> Deserializer<T> deserialize(Class<T> victim) {
return new Deserializer<T>(victim);
}
public static <T extends Enum<T>> Serializer<T> serialize(T victim) {
return new Serializer<T>(victim);
}
}
Sử dụng:
// Sender usage
EnumUtil.serialize(AwesomeEnum.Something).to(intent);
// Receiver usage
AwesomeEnum result =
EnumUtil.deserialize(AwesomeEnum.class).from(intent);
TÙY CHỌN 3 (với Kotlin):
Đã được một thời gian, nhưng kể từ bây giờ chúng tôi có Kotlin, tôi nghĩ rằng tôi sẽ thêm một tùy chọn khác cho mô hình mới. Ở đây chúng ta có thể sử dụng các hàm mở rộng và các kiểu hợp nhất (giữ lại kiểu khi biên dịch).
inline fun <reified T : Enum<T>> Intent.putExtra(victim: T): Intent =
putExtra(T::class.java.name, victim.ordinal)
inline fun <reified T: Enum<T>> Intent.getEnumExtra(): T? =
getIntExtra(T::class.java.name, -1)
.takeUnless { it == -1 }
?.let { T::class.java.enumConstants[it] }
Có một vài lợi ích của việc làm theo cách này.
- Chúng tôi không yêu cầu "chi phí chung" của một đối tượng trung gian để thực hiện tuần tự hóa vì tất cả đều được thực hiện nhờ vào
inline
đó sẽ thay thế các cuộc gọi bằng mã bên trong hàm.
- Các chức năng quen thuộc hơn vì chúng tương tự như các SDK.
- IDE sẽ tự động hoàn thành các chức năng này, điều đó có nghĩa là không cần phải có kiến thức trước đó về lớp tiện ích.
Một trong những nhược điểm là, nếu chúng ta thay đổi thứ tự của Emums, thì mọi tham chiếu cũ sẽ không hoạt động. Đây có thể là một vấn đề với những thứ như Ý định bên trong ý định đang chờ xử lý vì chúng có thể tồn tại trong các bản cập nhật. Tuy nhiên, trong thời gian còn lại, nó sẽ ổn thôi.
Điều quan trọng cần lưu ý là các giải pháp khác, như sử dụng tên thay vì vị trí, cũng sẽ thất bại nếu chúng tôi đổi tên bất kỳ giá trị nào. Mặc dù, trong những trường hợp đó, chúng tôi nhận được một ngoại lệ thay vì giá trị Enum không chính xác.
Sử dụng:
// Sender usage
intent.putExtra(AwesomeEnum.SOMETHING)
// Receiver usage
val result = intent.getEnumExtra<AwesomeEnum>()