por - estructura de android
Componentes de la arquitectura de Android: Uso de enumeraciones (2)
Me encontré con un problema similar. La respuesta de Devrim al tema fue muy útil. Sin embargo mi entidad tiene un nullable.
En este caso, la operación de inserción devuelve un error. Esto es causado por el miembro "código" primitivo en el tipo de enumeración.
He desarrollado la siguiente implemantación para resolver este error.
Primero arreglé el tipo de enumeración de la siguiente manera.
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;
}
}
Luego actualicé la entidad de la siguiente manera.
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;
}
}
Por lo tanto, podría administrar la propiedad de enumeración anulable en la base de datos de sala
Espero haber podido ayudar con una situación similar.
Feliz codificacion
¿Es posible usar un tipo Enum como un campo incrustado en una clase de Entidad con los nuevos Componentes de Arquitectura de Android y la Biblioteca de Persistencia de la Sala?
Mi entidad (con enumeración incrustada):
@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;
}
}
}
Mi TypeConverter:
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();
}
}
Cuando compilo esto, aparece un error que dice ''Error: (52, 12) error: Entities y Pojos deben tener un constructor público utilizable. Puede tener un constructor vacío o un constructor cuyos parámetros coincidan con los campos (por nombre y tipo) ''.
Actualizar 1 mi clase SyncEntity:
/ ** * Clase base para todas las entidades de sala que están sincronizadas. * /
@Entity
public class SyncEntity {
@ColumnInfo(name = "created_at")
Long createdAt;
@ColumnInfo(name = "updated_at")
Long updatedAt;
}
Puedo usar los valores de enumeración en Room
with TypeConverters
. Hay algunas partes para cambiar en su código:
1) Debe declarar que los campos de su Entidad son públicos o deben tener captadores / setters públicos. O obtendrás el siguiente error:
yourField no es público en YourEntity ; no se puede acceder desde el paquete exterior
2) No necesita la anotación @Embedded
para su campo de status
. Es para objetos anidados. Más de docs.
3) No @TypeConverters
anotación @TypeConverters
en el lugar correcto. En su caso, se puede establecer por encima del campo de status
. Más de docs.
4) Debe definir un constructor para su Entidad o obtendrá el siguiente error:
Las entidades y Pojos deben tener un constructor público utilizable. Puede tener un constructor vacío o un constructor cuyos parámetros coincidan con los campos (por nombre y tipo).
Puede definir un constructor vacío para omitir este error.
5) Use int en lugar de Integer en su TypeConverter.
Suma; a continuación funciona como se espera:
@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;
}
}
}