web-dev-qa-db-ja.com

Androidアーキテクチャコンポーネント:列挙型の使用

新しいAndroid Architecture Components and Room Persistence LibraryでEntityクラスの埋め込みフィールドとしてEnumタイプを使用することは可能ですか?

私のエンティティ(埋め込み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;
        }
    }
}

私の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();
    }
}

これをコンパイルすると、「Error:(52、12)error:Entities and Pojos must have a public constructor。」というエラーが表示されます。空のコンストラクターまたはパラメーターがフィールドに一致するコンストラクター(名前とタイプ)を持つことができます。

更新1 My SyncEntityクラス:

/ ** *同期されるすべての会議室エンティティの基本クラス。 * /

@Entity
public class SyncEntity {

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

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

Roomの列挙値をTypeConvertersとともに使用できます。コードで変更する部分がいくつかあります。

1)エンティティのフィールドをパブリックとして宣言するか、パブリックのゲッター/セッターが必要です。または、以下のエラーが表示されます:

yourFieldYourEntityでパブリックではありません;外部パッケージからアクセスできません

2)statusフィールドに@Embedded注釈は必要ありません。ネストされたオブジェクト用です。 ドキュメントの詳細

3)@TypeConverters注釈を正しい場所で使用していません。あなたの場合、statusフィールドの上に設定できます。 ドキュメントの詳細

4)エンティティのコンストラクタを定義する必要があります。そうしないと、以下のエラーが発生します。

エンティティとPojoには、使用可能なパブリックコンストラクターが必要です。空のコンストラクターまたはパラメーターがフィールドに一致するコンストラクター(名前とタイプによる)を持つことができます。

このエラーをスキップするには、空のコンストラクターを定義できます。

5)TypeConverterでIntegerの代わりにintを使用します。

和;以下は期待どおりに動作します:

@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;
        }
    }
}
38
Devrim

同様の問題が発生しました。この問題に対するDevrimの答えはとても役に立ちました。ただし、エンティティにはnull値を許可するエンティティがあります。

この場合、挿入操作はエラーを返します。これは、列挙型のプリミティブな「コード」メンバーが原因です。

このエラーを解決するために、次の実装を開発しました。

最初に列挙型を次のように修正しました。

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許容列挙型プロパティを管理できました。

同様の状況で私が助けられたことを願っています。

ハッピーコーディング。

8
Hasan BINBOGA