RealmObject的自定义反序列化器 [英] Custom deserializer for RealmObject

查看:76
本文介绍了RealmObject的自定义反序列化器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

出于学习目的,我正在使用Realm和Edinburg Festival Api创建一个android应用.除一个问题外,一切进展顺利.

For learning purposes i'm creating an android app by using Realm and the Edinburg Festival Api. It's going pretty well except for one problem.

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

I'm using the following to convert the retrieved JSON to RealmObjects:

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);
        }
    }
}

除了一个字段(图像)以外,此方法都可以正常工作. JSON的图片部分:

This works fine except for one field, the images. The image part of the JSON:

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

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

The problem here is the hash inside the image object. I have no clue how to handle this. The hash is different for every festival. Would it be possible to to make a custom JSON deserializer in my RealmObject?

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

Last code sample is my current model:

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;
}

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

I'm aware my PK is not optimal but this is still just testing to get the images working and i needed to set a PK for migrating.

欢迎任何提示,欢呼:)

Any tips are welcome, cheers :)

添加了图像模型:

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

更新2

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

Update 2

My attempt to parse the images before calling realm.createOrUpdateAllFromJson(Festival.class, response);

private void parseImages(String jsonString) throws JSONException {
    JSONArray jsonArr = new JSONArray(jsonString);
    for(int i = 0; i < jsonArr.length(); i++){
        JSONObject jsonObj = jsonArr.getJSONObject(i);
        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);
            } catch (JSONException e) {
                // Something went wrong!
            }
        }
    }
}

更新3

我创建了一个函数,用于清理从API中获取的损坏的JSON.它不是很好,但现在可以使用.它删除了哈希和怪异的版本,并将它们都放置在一个数组中.我敢肯定它可以更有效地编写,但是我会继续使用它,以便现在我可以继续处理我的应用程序的其余部分.看看我自己的答案.

Update 3

I created a function that cleans up the broken JSON i get from the API. It ain't very nice but it works for now. it removes the hashes and the wierd versions and just places them both in a array. I'm sure it could be more efficiently written but i'll just go with this so i can move on with the rest of my app for now. See my own answer.

推荐答案

我自己的临时解决方案:

my own temporary solution:

    /**
     * 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;
    }

希望它对某人有帮助:)但是请确保它不是整洁的.

Hope it helps someone :) But sure ain't neat.

这篇关于RealmObject的自定义反序列化器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆