RealmObject的自定义反序列化程序

时间:2016-11-10 19:06:31

标签: android json realm

出于学习目的,我正在使用Realm和Edinburg Festival Api创建一个Android应用程序。除了一个问题外,它还是很顺利的。

我正在使用以下内容将检索到的JSON转换为RealmObjects:

Option Explicit

Function IsName(NameOfName) As Boolean
    Dim check As Name

    On Error Resume Next
    Set check = ActiveWorkbook.Names(NameOfName)
    On Error GoTo 0

    If check Is Nothing Then
        IsName = False
    Else
        IsName = True
    End If

End Function

Sub TestIsName()
    Dim test As Boolean
    test = IsName("name1")
    Debug.Print (test)
End Sub

除了一个字段,图像外,这个工作正常。 JSON的图像部分:

public void onResponse(final String response) {
    realm.executeTransactionAsync(new Realm.Transaction(){
        @Override
        public void execute(Realm realm) {
            // Update our realm with the results
            parseImages();
            realm.createOrUpdateAllFromJson(Festival.class, response);
        }
    }
}

这里的问题是图像对象内的哈希。我不知道如何处理这个问题。每个节日的哈希都不同。是否可以在我的RealmObject中创建自定义JSON反序列化器?

最后一个代码示例是我当前的模型:

"images": {    
    "031da8b4bad1360eddea87e8820615016878b183": {
        "hash": "031da8b4bad1360eddea87e8820615016878b183",
        "orientation": "landscape",
        "type": "hero",
        "versions": {
            "large-1024": {
            "height": 213,
            "mime": "image/png",
            "type": "large-1024",
        }
        "width": 1024
    }
}

我知道我的PK不是最佳的,但这仍然只是测试以使图像正常工作,我需要设置PK以进行迁移。

欢迎任何提示,欢呼:)

更新

添加了图像模型:

public class Festival extends RealmObject {
    @PrimaryKey
    public String title;
    RealmList<Image> images;
    public String description_teaser;
    public String description;
    public String genre;
    public String age_category;
    public String website;
    public RealmList<Performance> performances;
    public int votes;
}

更新2

我尝试在调用realm.createOrUpdateAllFromJson(Festival.class,response)之前解析图像;

public class Image extends RealmObject {
    public String hash;
    public String orientation;
    public String type;
    RealmList<Version> versions;
}

更新3

我创建了一个函数来清理我从API获得的破坏的JSON。这不是很好,但它现在有效。它删除了哈希和奇怪的版本,只是将它们放在一个数组中。我确信它可以更有效地编写,但我会继续使用这个,所以我现在可以继续我的应用程序的其余部分。看看我自己的答案。

2 个答案:

答案 0 :(得分:1)

我自己的临时解决方案:

    /**
     * Function to fix the json coming from the Festival API
     * This is a bit more complicated then it needs to be but realm does not yet support @Serializedname
     * It removes the "large-1024" (and simllar) object and places the versions in a JSON version array
     * Then it removes the hashes and creates and images array. The JsonArray can now be parsed normally :)
     *
     * @param jsonString Result string from the festival api
     * @return JSONArray The fixed JSON in the form of a JSONArray
     * @throws JSONException
     */
    private JSONArray cleanUpJson(String jsonString) throws JSONException {
        JSONArray json = new JSONArray(jsonString);
        for(int i = 0; i < json.length(); i++){
            // We store the json Image Objects in here so we can remove the hashes
            Map<String,JSONObject> images = new HashMap<>();
            JSONObject festivalJson = json.getJSONObject(i);
            JSONObject imagesJson = (JSONObject)festivalJson.get("images");
            // Iterate each hash inside the images
            Iterator<String> hashIter = imagesJson.keys();
            while (hashIter.hasNext()) {
                String key = hashIter.next();
                try {
                    final JSONObject image = imagesJson.getJSONObject(key);

                    // Remove the version parents and map them to version
                    Map<String, JSONObject> versions = new HashMap<>();
                    JSONObject versionsJsonObject = image.getJSONObject("versions");

                    // Now iterate all the possible version and map add to the hashmap
                    Iterator<String> versionIter = versionsJsonObject.keys();
                    while(versionIter.hasNext()){
                        String currentVersion = versionIter.next();
                        versions.put(currentVersion,versionsJsonObject.getJSONObject(currentVersion));
                    }

                    // Use the hashmap to modify the json so we get an array of version
                    // This can't be done in the iterator because you will get concurrent error
                    image.remove("versions");
                    Iterator hashMapIter = versions.entrySet().iterator();
                    JSONArray versionJsonArray = new JSONArray();
                    while( hashMapIter.hasNext() ){
                        Map.Entry pair = (Map.Entry)hashMapIter.next();
                        versionJsonArray.put(pair.getValue());
                    }
                    image.put("versions",versionJsonArray);
                    Log.d(LOG_TAG,image.toString());
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                images.put(key,imagesJson.getJSONObject(key));
            }
            // Now let's get rid of the hashes
            Iterator hashMapIter = images.entrySet().iterator();
            JSONArray imagesJsonArray = new JSONArray();
            while( hashMapIter.hasNext() ){
                Map.Entry pair = (Map.Entry)hashMapIter.next();
                imagesJsonArray.put(pair.getValue());
            }
            festivalJson.put("images", imagesJsonArray);
        }
        return json;
    }

希望它可以帮助某人:)但是确定无所事事。

答案 1 :(得分:0)

由于这个JSON中的键是动态的(为什么不是这个数组?设计此API的人不知道他们在做什么),you'll have to manually parse the object up to the point of the hash key

JSONObject jsonObj = new JSONObject(jsonString);
JSONObject images = (JSONObject)jsonObj.get("images");
Iterator<String> iter = images.keys();
while (iter.hasNext()) {
    String key = iter.next();
    try {
        JSONObject value = json.get(key);
        realm.createOrUpdateObjectFromJson(Image.class, value.toString());
    } catch (JSONException e) {
        // Something went wrong!
    }
}