本文介绍了RealmList 序列化问题(Realm/Gson/Intent)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的项目中使用了 Retrofit、Gson 和 Realm.我有这个类Example需要Serializable.如果没有 Realm,我会这样写:

I use Retrofit, Gson and Realm in my project.I have this class Examplethat need to be Serializable. Without Realm I'd write it like that :

public class Example implements Serializable {
    @SerializationName("users")
    private List<String> users

    //... getters and setters
}

Realm 开始发挥作用,Example 变为(注意 getter 和 setter 是出于兼容性原因采用这种方式):

Realm comes into play and Example becomes (note that getters and setters are this way for compatibility reasons) :

public class Example extends RealmObject implement Serializable {

    @SerializedName("users")
    private RealmList<RealmString> users;

    public ArrayList<String> getUsers() {
        ArrayList<String> array = new ArrayList<>();
        for (RealmString rs : users) {
            array.add(rs.getValue());
        }
        return array;
    }

    public void setUsers(ArrayList<String> users) {
        RealmList<RealmString> array = new RealmList<>();
        for (String rs : users) {
            array.add(new RealmString(rs));
        }
        this.users = array;
    }

}

RealmString 为:

with RealmString being :

public class RealmString extends RealmObject implements Serializable {

    private String val;

    //Constructors, getter and setter
}

并添加自定义 Gson 类型转换器以使其正确反序列化:

and add a custom Gson type converter for it to be deserialized correctly :

public class RealmStringRealmListConverter implements JsonSerializer<RealmList<RealmString>>,
        JsonDeserializer<RealmList<RealmString>> {

    @Override
    public JsonElement serialize(RealmList<RealmString> src, Type typeOfSrc,
                                 JsonSerializationContext context) {
        JsonArray ja = new JsonArray();
        for (RealmString tag : src) {
            ja.add(tag.getValue());
        }
        return ja;
    }

    @Override
    public RealmList<RealmString> deserialize(JsonElement json, Type typeOfT,
                                              JsonDeserializationContext context)
            throws JsonParseException {
        RealmList<RealmString> tags = new RealmList<>();
        JsonArray ja = json.getAsJsonArray();
        for (JsonElement je : ja) {
            if (je.isJsonPrimitive()) {
                tags.add(new RealmString(je.getAsString()));
            }
        }
        return tags;
    }

}

好的,现在我们开始觉得 Realm 开始对我们的代码产生很大的影响.但这是一个附带问题,主要问题是 Example 不再是可序列化的:RealmList 不是.

Ok so now we're starting to feel that Realm is starting to have to big of an impact over our code. But that's a side problem, the main issue is that Example is no longer Serializable : RealmList isn't.

所以我尝试使 RealmList 成为瞬态并拥有我可以使用 @Ignore 注释的挂起列表,并在序列化后重新创建 RealmList.但 Realm 不接受瞬态.

so I tried to make the RealmList transient and have its pendent List that I can annotate with @Ignore, and recreate the RealmList after serialization. But transient is not accepted by Realm.

现在我觉得有点卡住了,Example 在我的代码的许多部分(它是很多类的成员)中通过意图传递.我不想使用 id 到处查询.

Now I feel a bit stuck, Example is passed through intents in numerous parts of my code (it's a member of a lot of classes). I don't want to use an id and query it everywhere.

我的问题是:

如何更改 ̀ Example` 以允许我执行 new Bundle().putSerializable("test", new Example()); 而不会崩溃.

How can I change ̀ Example` in a way that allows me to do new Bundle().putSerializable("test", new Example()); without crash.

感谢您的帮助!

推荐答案

Serializable 不适用于 RealmList,但您可以使用 Parceler 库并实现 Parcelable打包 RealmObjects(注意:它会将它们变成非托管副本!)

Serializable won't work with RealmList, but you can use Parceler library and implement Parcelable to parcel RealmObjects (note: it will turn them into unmanaged copies!)

@Parcel(implementations = { UserRealmProxy.class },
        value = Parcel.Serialization.BEAN,
        analyze = { User.class })
public class User extends RealmObject {
    // ...
}

compile "org.parceler:parceler-api:1.0.3"
apt "org.parceler:parceler:1.0.3"

parcel RealmList,使用以下代码

/* Copyright 2016 Patrick Löwenstein
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. */

public class RealmListParcelConverter implements TypeRangeParcelConverter<RealmList<? extends RealmObject>, RealmList<? extends RealmObject>> {
  private static final int NULL = -1;

  @Override
  public void toParcel(RealmList<? extends RealmObject> input, Parcel parcel) {
    if (input == null) {
      parcel.writeInt(NULL);
    } else {
      parcel.writeInt(input.size());
      for (RealmObject item : input) {
        parcel.writeParcelable(Parcels.wrap(item), 0);
      }
    }
  }

  @Override
  public RealmList fromParcel(Parcel parcel) {
    int size = parcel.readInt();
    RealmList list = new RealmList();

    for (int i=0; i<size; i++) {
      Parcelable parcelable = parcel.readParcelable(getClass().getClassLoader());
      list.add((RealmObject) Parcels.unwrap(parcelable));
    }

    return list;
  }
}

这篇关于RealmList 序列化问题(Realm/Gson/Intent)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-25 13:51