Android架构组件:使用枚举
使用新的Android架构组件和Room持久性库,是否可以将枚举类型用作实体类中的嵌入字段 我的实体(带有嵌入式枚举): 我的类型转换器:Android架构组件:使用枚举,android,android-room,android-architecture-components,Android,Android Room,Android Architecture Components,使用新的Android架构组件和Room持久性库,是否可以将枚举类型用作实体类中的嵌入字段 我的实体(带有嵌入式枚举): 我的类型转换器: public class StatusConverter { @TypeConverter public static Task.Status toStatus(int status) { if (status == ACTIVE.getCode()) { return ACTIVE;
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和pojo必须有一个可用的公共构造函数。您可以使用空构造函数,也可以使用参数与字段匹配的构造函数(按名称和类型)。
更新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;
}
我可以使用
房间
中的枚举值和类型转换器
。代码中有一些部分需要更改:
1)必须将实体的字段声明为公共字段,或者必须具有公共getter/setter。否则您将得到以下错误:
yourField在您的实体中不是公共的;无法从中访问
外包装
2)您的状态字段不需要@Embedded
注释。它用于嵌套对象
3)您没有在正确的位置使用@TypeConverters
注释。在您的情况下,它可以设置在状态
字段上方
4)必须为实体定义构造函数,否则会出现以下错误:
实体和POJO必须具有可用的公共构造函数。您可以有一个空构造函数,也可以有一个参数与字段(按名称和类型)匹配的构造函数
您可以定义一个空构造函数来跳过此错误
5)在类型转换器中使用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;
}
}
}
我遇到了类似的问题。德夫里姆对这个问题的回答很有帮助。然而,我的实体有一个可空的
在这种情况下,insert操作返回一个错误。这是由枚举类型中的基元“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;
}
}
然后我更新了实体,如下所示
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;
}
}
所以,我可以管理房间数据库中的可空枚举属性
我希望我能帮助解决类似的问题
愉快的编码。我认为您要么需要将字段公开
,要么提供公开
设置器,要么提供与@Query
列匹配的公开
构造函数。否则,文件室无法向您提供数据。唯一的构造函数是零参数构造函数。getter和setter不能解决问题,枚举也不允许使用公共构造函数。我原以为TypeConverter可以做到这一点,将枚举转换为int,但事实并非如此。也许房间还不够成熟,不适合这种用途。可能应该发出一个功能请求。感谢@Devrim提供的“在TypeConverter中使用int而不是Integer”如果必须在枚举中使用整数值,这是正确的方法。永远不要使用序号。不使用序号的原因是什么?如果常用的话,我更喜欢在数据库级别调用转换器。不使用序号的原因是,您可能会选择重新排列枚举的顺序(例如,如果添加一个新的枚举),因此当它从数据库中拉出时,您可能会将其映射到错误的值。你最好用一根绳子@盐城