Câu hỏi Android: Làm thế nào để đặt một Enum trong một Bundle?


Làm cách nào để thêm đối tượng Enum vào Gói Android?


245
2017-07-20 18:17


gốc


Theo tôi, lời khuyên từ nhân viên của Google là xấu. Enums là rất thuận tiện và bị chi phí trên được mô tả là đáng giá. - ognian
bạn có thể xem lại câu trả lời và chấp nhận câu trả lời thứ hai nếu bạn cho rằng đó có thể là lựa chọn tốt hơn. - philipp
Dưới tiêu đề "Tránh Enums" trong liên kết ở trên nó bây giờ nói điều này: Thần thoại hiệu suất Các phiên bản trước của tài liệu này đưa ra nhiều tuyên bố gây hiểu nhầm khác nhau. Chúng tôi giải quyết một số người trong số họ ở đây. - StackOverflowed
phần đó không còn hiện diện nữa. - Nathaniel D. Waggoner
có thể trùng lặp Vượt qua enum hoặc đối tượng thông qua một mục đích (giải pháp tốt nhất) - pablisco


Các câu trả lời:


Chỉ cần vượt qua nó như int từ thứ tự (). Khôi phục nó từ các giá trị [].


-23
2017-07-20 18:25



Điều này KHÔNG được đề nghị gì cả. Vấn đề là một trong những khả năng bảo trì. Intent có tiềm năng xuất phát từ các nguồn khác hoặc có nguồn gốc từ mã đọc dữ liệu cũ hơn phiên bản mã khôi phục enum từ Bundle. Do đó, thứ tự lưu có thể không tương ứng với chỉ số của giá trị enum chính xác. Các giải pháp được đề nghị là một bởi @miguel: để chỉ lưu trữ enum trực tiếp và khôi phục lại nó bằng cách gọi Intent # getSerializableExtra (String) và đưa trở lại kiểu enum. - Warlax
đồng bằng cũ xấu thấy stackoverflow.com/a/5309967/261363 - Calin
Vui lòng đánh dấu câu trả lời của @ miguel là câu trả lời đúng. Cảm ơn. - Abdellah Benhammou
Gói không nên được lưu trữ liên tục, vì vậy hãy đặt ordinal() đến savedInstanceState là thực hành hoàn toàn hợp lệ và chấp nhận được. - Miha_x64
@Warlax cảm ơn vì đã dành thời gian giải thích tại sao - Michael


Enums được Serializable nên không có vấn đề gì.

Cho enum sau đây:

enum YourEnum {
  TYPE1,
  TYPE2
}

Gói:

// put
bundle.putSerializable("key", YourEnum.TYPE1);

// get 
YourEnum yourenum = (YourEnum) bundle.get("key");

Mục đích:

// put
intent.putExtra("key", yourEnum);

// get
yourEnum = (YourEnum) intent.getSerializableExtra("key");

568
2018-03-15 09:48



Có điều gì sai với phương pháp này không: outState.putSerializable("trollData", game.getFunkyTrolls()); tải: game.setFunkyTrolls((Game.FunkyTroll[]) savedInstanceState.getSerializable("trollData")); ? - Moberg
Tôi đã bình chọn cho câu trả lời của bạn, nhưng câu hỏi là thêm Enum vào một Bundle và câu trả lời của bạn giải thích cách thêm nó vào Intent ... Cấp nó gần như giống nhau, nhưng Alejandro bên dưới đã sửa câu trả lời của bạn. - Pooks
khi sử dụng nó với Bundle, nó ném ClassNotFoundException - Sarge Borsch
điều này có thể siêu chậm và không quy mô thành các mảng có chứa enum, v.v. stackoverflow.com/a/5551155/175156 - yincrash
@yincrash enum sử dụng serialization tùy chỉnh khá nhanh. Bằng chứng: docs.oracle.com/javase/1.5.0/docs/guide/serialization/spec/… - Miha_x64


Tôi biết đây là một câu hỏi cũ, nhưng tôi đến cùng một vấn đề và tôi muốn chia sẻ cách tôi giải quyết nó. Điều quan trọng là những gì Miguel nói: Enums là Serializable.

Cho enum sau đây:

enum YourEnumType {
    ENUM_KEY_1, 
    ENUM_KEY_2
}

Đặt:

Bundle args = new Bundle();
args.putSerializable("arg", YourEnumType.ENUM_KEY_1);

149
2017-08-09 11:28



đây phải là câu trả lời được chấp nhận ... - Mars
Dựa vào cái này: stackoverflow.com/questions/15521309/…, Enums tùy chỉnh không được tuần tự hóa. Vì vậy, các trường tùy chỉnh trong một Enum sẽ không được đăng. Làm thế nào để bạn đối phó với điều này? - clu
Câu hỏi hay đấy @clu! Có lẽ sau đó bạn nên nghĩ rằng nó là một chuỗi như đã nói trong stackoverflow.com/questions/609860/… - Alejandro Colorado
@clu Bằng cách không mong đợi các trường tùy chỉnh được tuần tự hóa. Nó hoạt động tốt nếu nó chỉ là một enum bình thường như trong đoạn mã trên. - bluehallu
Câu trả lời của Miguel đã được chỉnh sửa vào năm 2015. Câu trả lời ban đầu không nói gì về bó, nó chỉ cho thấy một ví dụ về mục đích. - Alejandro Colorado


Vì lợi ích đầy đủ, đây là một ví dụ đầy đủ về cách đưa vào và lấy lại một enum từ một gói.

Cho enum sau đây:

enum EnumType{
    ENUM_VALUE_1,
    ENUM_VALUE_2
}

Bạn có thể đặt enum vào một gói:

bundle.putSerializable("enum_key", EnumType.ENUM_VALUE_1);

Và lấy lại enum:

EnumType enumType = (EnumType)bundle.getSerializable("enum_key");

32
2018-03-05 03:11





Nó có thể tốt hơn để chuyển nó thành chuỗi từ myEnumValue.name () và khôi phục nó từ YourEnums.valueOf (s), nếu không, thứ tự của enum phải được giữ nguyên!

Giải thích dài hơn: Chuyển đổi từ enum thứ tự thành loại enum


15
2018-02-15 18:23



Việc sắp xếp không quan trọng nếu việc tuần tự hóa - deserialization xảy ra ngay lập tức khi chạy, chẳng hạn như khi gọi từ một hoạt động này sang hoạt động khác. Nó có thể là một vấn đề trong các quá trình như gửi Intents từ một ứng dụng đến một phiên bản cũ của ứng dụng. - miguel


Tôi dùng kotlin.

companion object {

        private enum class Mode {
            MODE_REFERENCE,
            MODE_DOWNLOAD
        }
}

sau đó đưa vào Intent:

intent.putExtra(KEY_MODE, Mode.MODE_DOWNLOAD.name)

khi bạn net để có được giá trị:

mode = Mode.valueOf(intent.getStringExtra(KEY_MODE))

14
2017-12-01 12:41



Làm thế nào điều này sẽ được lưu trữ cho onSaveInstanceState ()? - Adam Hurwitz
Câu trả lời này là câu trả lời thuận tiện nhất. - Wajid Ali


Một tùy chọn khác:

public enum DataType implements Parcleable {
    SIMPLE, COMPLEX;

    public static final Parcelable.Creator<DataType> CREATOR = new Creator<DataType>() {

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

        @Override
        public DataType createFromParcel(Parcel source) {
            return DataType.values()[source.readInt()];
        }
    };

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

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

4
2018-06-25 15:19



Bạn có thể sử dụng putSerializable(key, value)/(Type) getSerializable(key) hoặc là putString(key, value.name())/Type.valueOf(getString(key))Việc thực thi Parcelable ở đây là thừa và vô nghĩa. - Miha_x64