将云端点模型类序列化为Android文件系统的方法

jdu*_*dub 4 serialization android caching google-cloud-endpoints

我已成功创建了一个云端点模型,可以轻松从App Engine中检索信息.为了减少往返次数并提供更快的用户体验,我已经确定了一个我希望存储到本地存储的实例.

在我的应用程序的其余部分中,我使用ObjectInputStream来读取和写入对象,例如:

FileInputStream fis = context.openFileInput("PRIVFILE");
ObjectInputStream ois = new ObjectInputStream(fis);
AppModelState s = (AppModelState) ois.readObject();
Run Code Online (Sandbox Code Playgroud)

这显然要求所有数据成员实现Serializable接口.Model类扩展GenericJSON并且不是"Serializable",如

    public final class ModelClass extends GenericJson {}
Run Code Online (Sandbox Code Playgroud)

我可以手动创建一个映射到模型的可序列化对象; 然而,由于属性的数量,这似乎非常业余.

我考虑的另一个选择是创建一个Serializable Object包装器,它只是将JSON字符串作为成员,并提供一个setter/getter接受ModelClass作为参数,例如:

class AppModelState implements Serializable {
   private String modelClassJSON;

   public ModelClass getModelClass() {
      // generate a new ModelClass from the JSON
   }

   public void setModelClass(ModelClass c) {
      // extract the JSON for storage
   }

   .....
}
Run Code Online (Sandbox Code Playgroud)

我觉得必须有一个更好的方法,这应该已经解决了十几次,但我找不到任何资源.请提供意见.

Bri*_*ite 6

我和你在问题中的说法完全一样.

由于Cloud Endpoints对象已经被序列化以通过线路传输,因此它们也可以序列化以便在本地存储.作为额外的奖励,使用Android 3.0或更高版本,您甚至不需要导入任何库 - 它已经存在!例如:

import com.google.api.client.extensions.android.json.AndroidJsonFactory;
import com.google.api.client.json.GenericJson;
import com.google.api.client.json.JsonFactory;

private static final JsonFactory JSON_FACTORY = new AndroidJsonFactory();

public void putObject(String key, Object value) throws Exception {
    byte[] outputbytes = null;
    if (value instanceof GenericJson) {
        outputbytes = JSON_FACTORY.toByteArray(value);
    } else {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        ObjectOutputStream objectstream = new ObjectOutputStream(output);
        objectstream.writeObject(value);
        objectstream.close();
        outputbytes = output.toByteArray();
    }

    // persist "outputbytes" ...
}

public <T> T getObject(String key, Class<T> outclass) throws Exception {
    // retrieve saved bytes...
    byte[] valuebytes = ...

    if (valuebytes[0] == '{' && valuebytes[1] == '"' && valuebytes[valuebytes.length-1] == '}') {
        // Looks like JSON...
        return JSON_FACTORY.fromString(new String(valuebytes, "UTF-8"), outclass);
    } else {
        ByteArrayInputStream input = new ByteArrayInputStream(valuebytes);
        ObjectInputStream objectstream = new ObjectInputStream(input);
        Object value = objectstream.readObject();
        objectstream.close();
        return outclass.cast(value);
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,AndroidJsonFactory序列化长字符串时,默认情况下(从Android v4.3起,无论如何)都很慢.JacksonFactory如果遇到性能问题,请创建一个新的.其他一切都保持不变.

更新: 如果要序列化GenericJson对象列表,则只需创建一个包含这些对象列表的GenericJson对象.例如:

import com.google.api.client.json.GenericJson;
import com.google.api.client.util.Key;

public static class PersistantJson extends GenericJson {
    @Key public int one;
    @Key public String two;
}

public static class PersistantJsonList extends GenericJson {
    @Key public List<PersistantJson> list = new ArrayList<PersistantJson>();
}
Run Code Online (Sandbox Code Playgroud)

您现在可以将所有PersistantJson(即"生成云端点客户端库"创建的某些类)对象添加到变量.list元素中PersistantJsonList,然后将该变量传递给putObject().请注意,这要求列表中的所有对象属于同一个类,以便反序列化知道类型是什么(因为JSON序列化不记录类型).如果你使用List<Object>那么回读的是a List<Map<String, Object>>,你必须手动提取字段.