RealmObject的自定义反序列化器 [英] Custom deserializer for 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屋!