Làm việc với Enums trong Android


120

Tôi gần như đã hoàn thành một hoạt động tính toán mà tôi đang làm việc với Android cho ứng dụng của mình. Tôi cố gắng tạo Gender Enum, nhưng vì lý do nào đó mà bị lỗi Cú pháp, hãy chèn "EnumBody" để hoàn thành EnumDec Tuyên bố.

public static enum Gender
{
    static
    {
        Female = new Gender("Female", 1);
        Gender[] arrayOfGender = new Gender[2];
        arrayOfGender[0] = Male;
        arrayOfGender[1] = Female;
        ENUM$VALUES = arrayOfGender;
    }
}

Tôi cũng đã thử nó mà không có {} tĩnh nhưng tôi gặp lỗi cú pháp tương tự.


Enums không được khuyến nghị cho các vấn đề về hiệu suất, thay vào đó hãy sử dụng các hằng số nguyên thủy. youtube.com/watch?v=Hzs6OBcvNQE
Myke Dev

CẬP NHẬT 2019: Enums có thể sử dụng trong Android vì ART đã thay thế DALVIK làm môi trường thời gian chạy stackoverflow.com/a/56296746/4213436 . Vì vậy, tôi nghĩ rằng hầu hết các câu trả lời trên chủ đề này là không liên quan.
JDenais

@JDena, dĩ nhiên ý bạn là chuỗi 'bạn' vừa được tham chiếu
YoussefDir

Câu trả lời:


343

Bạn tìm thấy cú pháp này ở đâu? Java Enums rất đơn giản, bạn chỉ cần chỉ định các giá trị.

public enum Gender {
   MALE,
   FEMALE
}

Nếu bạn muốn chúng phức tạp hơn, bạn có thể thêm giá trị cho chúng như thế này.

public enum Gender {
    MALE("Male", 0),
    FEMALE("Female", 1);

    private String stringValue;
    private int intValue;
    private Gender(String toString, int value) {
        stringValue = toString;
        intValue = value;
    }

    @Override
    public String toString() {
        return stringValue;
    }
}

Sau đó, để sử dụng enum, bạn sẽ làm như sau:

Gender me = Gender.MALE

12
Tôi sẽ cho rằng một thử, tôi đã nói rằng tôi là một người mới bắt đầu tuyệt đối
JMSDEV

87
Xin lỗi, tôi không có ý tiêu cực như vậy. Chỉ cần cú pháp kỳ lạ nhất mà tôi từng thấy cho một Enum
Spidy

4
Nó cũng hữu ích khi đề cập đến các enum là tuần tự để bạn có thể sử dụng .ordinal () trên enum để nhận giá trị int.
Kalel Wade

1
Cú pháp trong câu hỏi là kiểu mà người ta có thể nghĩ ra khi sử dụng trình dịch ngược.
Dan Getz

9
Tôi đã cười rất nhiều về "Nơi trái đất mà bạn tìm thấy cú pháp này". Nói giống như một giáo viên để học trò của mình
Zar E Ahmer

50

Đã có một số cuộc tranh luận xung quanh quan điểm tranh cãi này, nhưng ngay cả trong các tài liệu gần đây nhất, android cũng cho thấy rằng việc sử dụng enum trong ứng dụng android không phải là một ý kiến ​​hay. Lý do tại sao là vì chúng sử dụng nhiều bộ nhớ hơn một biến hằng số tĩnh. Đây là tài liệu từ một trang năm 2014 khuyên không nên sử dụng enum trong ứng dụng Android. http://developer.android.com/training/articles/memory.html#Overhead

Tôi trích dẫn:

Lưu ý về chi phí bộ nhớ

Hiểu biết về chi phí và chi phí của ngôn ngữ và thư viện bạn đang sử dụng, đồng thời ghi nhớ thông tin này khi bạn thiết kế ứng dụng của mình, từ đầu đến cuối. Thông thường, những thứ bề ngoài trông có vẻ vô hại thực tế có thể có một lượng lớn chi phí. Những ví dụ bao gồm:

  • Enums thường yêu cầu bộ nhớ nhiều hơn gấp đôi so với hằng số tĩnh. Bạn nên tránh hoàn toàn việc sử dụng enums trên Android.

  • Mọi lớp trong Java (bao gồm cả các lớp ẩn danh bên trong) sử dụng khoảng 500 byte mã.

  • Mỗi cá thể lớp có 12-16 byte RAM trên đầu.

  • Việc đưa một mục nhập duy nhất vào HashMap yêu cầu cấp phát đối tượng mục nhập bổ sung chiếm 32 byte (xem phần trước về vùng chứa dữ liệu được tối ưu hóa).

Một vài byte ở đây và ở đó sẽ nhanh chóng được cộng lại — các thiết kế ứng dụng mang tính phân loại hoặc đối tượng nặng sẽ bị ảnh hưởng bởi chi phí này. Điều đó có thể khiến bạn rơi vào tình thế khó khăn khi xem xét phân tích đống và nhận ra vấn đề của bạn là rất nhiều vật thể nhỏ đang sử dụng hết RAM của bạn.

Đã có một số nơi họ nói rằng những lời khuyên này đã lỗi thời và không còn giá trị nữa, nhưng lý do họ tiếp tục lặp lại nó, phải có một số sự thật. Viết một ứng dụng android là điều bạn nên giữ càng nhẹ càng tốt để có trải nghiệm người dùng mượt mà. Và mỗi inch hiệu suất nhỏ đều có giá trị!


Đã có một số địa điểm - bạn có thể thêm một số địa điểm nếu bạn biết? vì tôi không thể tìm thấy bất kỳ
Krzysztof Skrzynecki

9
Ở đây, ai đó nhận thấy rằng thông tin về việc sử dụng ints thay vì enums đã bị xóa khỏi Mẹo hiệu suất trong tài liệu chính thức. Hơn nữa, tôi đã thực hiện nghiên cứu và đăng tóm tắt trên reddit
Krzysztof Skrzynecki

1
Mô hình hiệu suất của Android: Giá của ENUM (100 ngày của Google Dev)
Afriza N. Tóm tắt

Các bạn ơi, câu hỏi của mình là nếu Enum thực hành "xấu", tại sao Google vẫn hỗ trợ tính năng này của Java với Android? :(
Jesús Castro

5
@ JesúsCastro Bởi vì Google muốn đảm bảo rằng các công ty có nhiều logic nghiệp vụ Java hiện có (có thể đang sử dụng enums) có thể thả thư viện của họ vào một dự án Android và đi.
David Brown

22

Như nhận xét của Chris, enum yêu cầu nhiều bộ nhớ hơn trên Android, vốn sẽ tăng lên khi chúng tiếp tục được sử dụng ở mọi nơi. Bạn nên thử IntDef hoặc StringDef để thay thế, sử dụng chú thích để trình biên dịch xác thực các giá trị đã truyền.

public abstract class ActionBar {
...
@IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS})
@Retention(RetentionPolicy.SOURCE)
public @interface NavigationMode {}

public static final int NAVIGATION_MODE_STANDARD = 0;
public static final int NAVIGATION_MODE_LIST = 1;
public static final int NAVIGATION_MODE_TABS = 2;

@NavigationMode
public abstract int getNavigationMode();

public abstract void setNavigationMode(@NavigationMode int mode);

Nó cũng có thể được sử dụng như cờ, cho phép thành phần nhị phân (phép toán OR / AND).

CHỈNH SỬA : Có vẻ như việc chuyển đổi enum thành int là một trong những cách tối ưu hóa mặc định trong Proguard .


3
Tôi thích đặt hằng số int trực tiếp vào lớp chú thích. Vì vậy, nó trông giống như enum thông thường. Tôi đã mô tả nó ở đây: blog.shamanland.com/2016/02/int-string-enum.html
Oleksii K.


9

Theo Video này nếu bạn sử dụng ProGuard, bạn thậm chí không cần phải suy nghĩ về các vấn đề hiệu suất Enums !!

Trong nhiều trường hợp, Proguard có thể thay mặt bạn tối ưu hóa giá trị Enums thành INT nên bạn thực sự không cần phải suy nghĩ về nó hoặc thực hiện bất kỳ công việc nào.


4

Cách tiếp cận ưa thích của Android là hằng số int được thực thi với @IntDef:

public static final int GENDER_MALE = 1;
public static final int GENDER_FEMALE = 2;

@Retention(RetentionPolicy.SOURCE)
@IntDef ({GENDER_MALE, GENDER_FEMALE})
public @interface Gender{}

// Example usage...
void exampleFunc(@Gender int gender) {
  switch(gender) {
  case GENDER_MALE:

     break;
  case GENDER_FEMALE:
     // TODO
     break;
  }
}

Tài liệu: https://developer.android.com/studio/write/annotations.html#enum-annotations

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.