Android 架构组件:使用枚举
Android Architecture Components: Using Enums
是否可以使用新的 Android 架构组件和 Room Persistence 库将枚举类型用作实体 class 中的嵌入字段?
我的实体(带有嵌入式枚举):
@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. You can have an empty constructor or a constructor whose parameters match the fields (by name and type).
更新 1
我的同步实体 class:
/**
* 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) 您必须声明实体的字段 public 或它们必须具有 public getters/setters。或者你会得到以下错误:
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;
}
}
}
我遇到了类似的问题。 Devrim 对该主题的回答非常有帮助。但是我的实体有一个可以为空的实体。
在这种情况下,插入操作returns出错。这是由枚举类型中的原始 "code" 成员引起的。
我开发了以下实现来解决此错误。
首先我将枚举类型固定如下。
package com.example.models.entities.enums;
import androidx.room.TypeConverter;
public enum Status {
ACTIVE(0),
INACTIVE(1),
COMPLETED(2);
private final Integer code;
Status(Integer value) {
this.code = value;
}
public Integer getCode() {
return code;
}
@TypeConverter
public static Status getStatus(Integer numeral){
for(Status ds : values()){
if(ds.code == numeral){
return ds;
}
}
return null;
}
@TypeConverter
public static Integer getStatusInt(Status status){
if(status != null)
return status.code;
return null;
}
}
然后我更新实体如下。
package com.example.models.entities;
import com.example.models.TypeConverters.DateConverter;
import com.example.models.entities.enums.Status;
import java.util.Date;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
import androidx.room.TypeConverters;
@Entity(tableName = "tasks")
@TypeConverters({Status.class, DateConverter.class})
public class Task extends SyncEntity {
@PrimaryKey(autoGenerate = true)
String taskId;
@NonNull
String title;
/** Status of the given task.
* Enumerated Values: 0 (Active), 1 (Inactive), 2 (Completed)
*/
@Nullable
Status status;
@NonNull
Date startDate;
public String getTaskId() {
return taskId;
}
public void setTaskId(String taskId) {
this.taskId = taskId;
}
@NonNull
public String getTitle() {
return title;
}
public void setTitle(@NonNull String title) {
this.title = title;
}
@Nullable
public Status getStatus() {
return status;
}
public void setStatus(@Nullable Status status) {
this.status = status;
}
@NonNull
public Date getStartDate() {
return startDate;
}
public void setStartDate(@NonNull Date startDate) {
this.startDate = startDate;
}
}
因此,我可以在 Room 数据库中管理可为 null 的枚举 属性。
我希望我能在类似情况下提供帮助。
编码愉快。
是否可以使用新的 Android 架构组件和 Room Persistence 库将枚举类型用作实体 class 中的嵌入字段?
我的实体(带有嵌入式枚举):
@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. You can have an empty constructor or a constructor whose parameters match the fields (by name and type).
更新 1 我的同步实体 class:
/**
* 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) 您必须声明实体的字段 public 或它们必须具有 public getters/setters。或者你会得到以下错误:
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;
}
}
}
我遇到了类似的问题。 Devrim 对该主题的回答非常有帮助。但是我的实体有一个可以为空的实体。
在这种情况下,插入操作returns出错。这是由枚举类型中的原始 "code" 成员引起的。
我开发了以下实现来解决此错误。
首先我将枚举类型固定如下。
package com.example.models.entities.enums;
import androidx.room.TypeConverter;
public enum Status {
ACTIVE(0),
INACTIVE(1),
COMPLETED(2);
private final Integer code;
Status(Integer value) {
this.code = value;
}
public Integer getCode() {
return code;
}
@TypeConverter
public static Status getStatus(Integer numeral){
for(Status ds : values()){
if(ds.code == numeral){
return ds;
}
}
return null;
}
@TypeConverter
public static Integer getStatusInt(Status status){
if(status != null)
return status.code;
return null;
}
}
然后我更新实体如下。
package com.example.models.entities;
import com.example.models.TypeConverters.DateConverter;
import com.example.models.entities.enums.Status;
import java.util.Date;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
import androidx.room.TypeConverters;
@Entity(tableName = "tasks")
@TypeConverters({Status.class, DateConverter.class})
public class Task extends SyncEntity {
@PrimaryKey(autoGenerate = true)
String taskId;
@NonNull
String title;
/** Status of the given task.
* Enumerated Values: 0 (Active), 1 (Inactive), 2 (Completed)
*/
@Nullable
Status status;
@NonNull
Date startDate;
public String getTaskId() {
return taskId;
}
public void setTaskId(String taskId) {
this.taskId = taskId;
}
@NonNull
public String getTitle() {
return title;
}
public void setTitle(@NonNull String title) {
this.title = title;
}
@Nullable
public Status getStatus() {
return status;
}
public void setStatus(@Nullable Status status) {
this.status = status;
}
@NonNull
public Date getStartDate() {
return startDate;
}
public void setStartDate(@NonNull Date startDate) {
this.startDate = startDate;
}
}
因此,我可以在 Room 数据库中管理可为 null 的枚举 属性。
我希望我能在类似情况下提供帮助。
编码愉快。