存储int []和String []的Android领域

时间:2015-01-24 18:43:43

标签: java android arrays realm

有没有办法存储int []和String [],除了创建一个包含它们的新对象,然后将它存储在realmList中

我有一个对象,它接受String,int []和String []的参数。你不能在领域中存储int []和String [],所以我创建了一个对象

public class Workouts extends RealmObject {

    private String workout;

    public Workouts() {

    }

    public Workouts(String workout) {
        this.workout = workout;
    }

    public String getWorkout() {
        return workout;
    }

    public void setWorkout(String workout) {
        this.workout = workout;
    }
}

public class Multiplier extends RealmObject {

    private int multiplier;

    public Multiplier() {

    }

    public Multiplier(int multiplier) {
        this.multiplier = multiplier;
    }

    public int getMultiplier() {
        return multiplier;
    }

    public void setMultiplier(int multiplier) {
        this.multiplier = multiplier;
    }
}

然后我将它们存储起来 RealmList乘数; RealmList锻炼;

我想知道是否有一种方法可以通过使用数组而不是RealmList来存储它们

3 个答案:

答案 0 :(得分:8)

来自Realm的Emanuele。现在除了包装String或int之外别无其他方法,并在那些上使用RealmList。这有几个原因,包括能够在不同平台上使用Realm文件。这在您的用例中是否是可接受的解决方案,还是一种痛苦?

如果您愿意,这个要点演示了如何使用RealmList在RealmObject中存储一组原始值。 https://gist.github.com/cmelchior/1a97377df0c49cd4fca9

答案 1 :(得分:4)

创建RealmString类,如下所示

public class RealmString extends RealmObject {
    private String val;
    public RealmString(){
    }

    public RealmString(String value) {
        this.val = value;
    }

    public String getValue() {
        return val;
    }

    public void setValue(String value) {
        this.val = value;
    }


    @Override
    public String toString() {
        return val;
    }
}

创建新班级

public class RealmStringDeserializer implements JsonDeserializer<RealmList<RealmString>> {

    @Override
    public RealmList<RealmString> deserialize(JsonElement json, Type typeOfT,
                                              JsonDeserializationContext context) throws JsonParseException {

        RealmList<RealmString> realmStrings = new RealmList<>();
        JsonArray stringList = json.getAsJsonArray();

        for (JsonElement stringElement : stringList) {
            realmStrings.add(new RealmString(stringElement.getAsString()));
        }

        return realmStrings;
    }
}

如果您使用领域进行改造,请将以下行添加到您的改造构建器类

Gson gson = new GsonBuilder()
                .setLenient()
                .setExclusionStrategies(new ExclusionStrategy() {
                    @Override
                    public boolean shouldSkipField(FieldAttributes f) {
                        return f.getDeclaringClass().equals(RealmObject.class);
                    }

                    @Override
                    public boolean shouldSkipClass(Class<?> clazz) {
                        return false;
                    }
                })
                .registerTypeAdapter(new TypeToken<RealmList<RealmString>>() {
                }.getType(), new RealmStringDeserializer())
                .create();

        if (retrofit == null) {
            retrofit = new Retrofit.Builder()
                    .baseUrl(NetworkConstants.BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create(gson))
                    .build();
        }

答案 2 :(得分:1)

我不喜欢使用RealmString和RealmInt。例如,当列表更改时,您将如何跟踪再次删除它们?

我为Realm-GSON(Retrofit)组合构建了一个自定义解决方案,它们共享相同的模型对象。我只测试了10个json文件。如果您发现任何问题,请告诉我,我会对此进行完善。

首先,在RealmObject中创建一个String而不是int []或String []:

/* 
 * Languages this user selected. Comma separated String.
 */
@SerializedName("languages")
private String languages;

然后为它创建getter和setter。请注意,StringUtils.join()是我自己的方法,如果您使用的库中没有它,那么您可以在网上的任何位置找到它。

/**
 * All user languages.
 */
public void setLanguagesFromList(List<String> languages) {

    String languagesStr = languages == null ? "" : StringUtils.join(languages, ",");
    if (!TextUtils.equals(this.languages, languagesStr)) {
        setDirty(true);
    }
    this.languages = languagesStr;
}

/**
 * Returns an unmodifiableList with all user languages.
 * <p>
 * Use setLanguagesFromList with a new list to make changes.
 *
 * @return
 */
public List<String> getLanguagesList() {

    return Collections.unmodifiableList(
            languages == null ? new ArrayList<>() :
                    Arrays.asList(languages.split(",")));
}

如果你经常使用这个getter,你可能想创建一个未保存在数据库中的List<String>(@Ignore),但是用于加速这个方法(这样只能在更改时进行解析/第一次访问)。

然后为GSON / Retrofit创建一个Deserializer:

/**
 * Used so that string (or any other primitive) arrays are parsed int one String. Realm cannot handle String arrays.
 */
public class RealmPrimitiveArrayDeserializer implements
    JsonDeserializer<String> {

private final static String KOMMA = ",";

  @Override
  public String deserialize(JsonElement json, Type typeOfT,
                          JsonDeserializationContext context) throws JsonParseException {

    if (json.isJsonNull()) {
        return null;
    }

    if (json.isJsonArray()) {

        StringBuilder targetStringBuilder = null;
        JsonArray stringList = json.getAsJsonArray();

        for (JsonElement element : stringList) {

            if (element.isJsonPrimitive()) {

                if (targetStringBuilder == null) {
                    targetStringBuilder = new StringBuilder();
                }

                targetStringBuilder.append(element.getAsString());
                targetStringBuilder.append(KOMMA);
            }
        }

        if (targetStringBuilder != null && targetStringBuilder.length() > 0) { 

            // remove the last komma:
            targetStringBuilder.deleteCharAt(targetStringBuilder.length() - 1);

            return targetStringBuilder.toString();
        }
    }

    return json.getAsString();
  }
}

将此添加到Retrofit使用的GSON配置中:

GsonBuilder gsonBuilder = new GsonBuilder()
                .registerTypeAdapter(new TypeToken<String>() {
                }.getType(), new RealmPrimitiveArrayDeserializer());

那就是它。祝你好运。