Android 架构组件 : Using Enums

标签 android android-room android-architecture-components

是否可以通过新的 Android 架构组件和 Room Persistence 库将 Enum 类型用作实体类中的嵌入字段?

我的实体(带有嵌入式枚举):

@Entity(tableName = "tasks")
public class Task extends SyncEntity {

    @PrimaryKey(autoGenerate = true)
    String taskId;

    String title;

    /** Status of the given task.
     * Enumerated Values: 0 (Active), 1 (Inactive), 2 (Completed)
     */
    @Embedded
    Status status;

    @TypeConverters(DateConverter.class)
    Date startDate;

    @TypeConverters(StatusConverter.class)
    public enum Status {
        ACTIVE(0),
        INACTIVE(1),
        COMPLETED(2);

        private int code;

        Status(int code) {
            this.code = code;
        }

        public int getCode() {
            return code;
        }
    }
}

我的类型转换器:

public class StatusConverter {

    @TypeConverter
    public static Task.Status toStatus(int status) {
        if (status == ACTIVE.getCode()) {
            return ACTIVE;
        } else if (status == INACTIVE.getCode()) {
            return INACTIVE;
        } else if (status == COMPLETED.getCode()) {
            return COMPLETED;
        } else {
            throw new IllegalArgumentException("Could not recognize status");
        }
    }

    @TypeConverter
    public static Integer toInteger(Task.Status status) {
        return status.getCode();
    }
}

当我编译这个时,我得到一个错误提示 Error:(52, 12) error: Entities and Pojos must have a usable public constructor。你可以有一个空的构造函数或一个参数与字段匹配的构造函数(按名称和类型)。

更新 1 我的 SyncEntity 类:

/**
 * Base class for all Room entities that are synchronized.
 */
@Entity
public class SyncEntity {

    @ColumnInfo(name = "created_at")
    Long createdAt;

    @ColumnInfo(name = "updated_at")
    Long updatedAt;
}

最佳答案

我可以将 Room 中的枚举值与 TypeConverters 一起使用。您的代码有一些部分需要更改:

1) 您必须将实体的字段声明为公开,或者它们必须具有公开的 getter/setter。否则你会得到以下错误:

yourField is not public in YourEntity; cannot be accessed from outside package

2) 您的 status 字段不需要 @Embedded 注释。它用于嵌套对象。 More from docs.

3) 您没有在正确的位置使用 @TypeConverters 注释。在您的情况下,它可以设置在 status 字段上方。 More from docs.

4) 你必须为你的实体定义一个构造函数,否则你会得到以下错误:

Entities and Pojos must have a usable public constructor. You can have an empty constructor or a constructor whose parameters match the fields (by name and type).

你可以定义一个空的构造函数来跳过这个错误。

5) 在 TypeConverter 中使用 int 而不是 Integer。

总和;下面按预期工作:

@Entity(tableName = "tasks")
public class Task extends SyncEntity {

    @PrimaryKey(autoGenerate = true)
    public String taskId;

    public String title;

    /** Status of the given task.
     * Enumerated Values: 0 (Active), 1 (Inactive), 2 (Completed)
     */
    @TypeConverters(StatusConverter.class)
    public Status status;

    @TypeConverters(DateConverter.class)
    public Date startDate;

    // empty constructor 
    public Task() {
    }

    public enum Status {
        ACTIVE(0),
        INACTIVE(1),
        COMPLETED(2);

        private int code;

        Status(int code) {
            this.code = code;
        }

        public int getCode() {
            return code;
        }
    }
}

关于Android 架构组件 : Using Enums,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44498616/

相关文章:

java - android list 中的多个应用程序

android - 更改 LiveData 以更新 RecyclerView。正确的方法?

android - 使用房间架构为嵌套的 JSON 对象创建表

android - 导航架构组件 - 带有 CollapsingToolbar 的详细 View

带有 BottomNavigationView 的 Android Jetpack Navigation 正确返回堆栈

android - 使用Android架构组件LiveData&ViewModel时是否需要使用onSaveInstanceState和onRestoreInstanceState?

Android Firebase 数据库事务

java - Android Java 使用 switch/case 来计算不同的百分比

android - R 无法解析为变量 - Android- Eclipse Fresh Project

android - Room 中的一对多关系