RealmObject的自定义解串器
为了学习的目的,我使用Realm和Edinburg Festival Api创建了一个Android应用程序。除了一个问题之外,它会很好。RealmObject的自定义解串器
我使用以下检索到的JSON转换为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的图像部分:
"images": {
"031da8b4bad1360eddea87e8820615016878b183": {
"hash": "031da8b4bad1360eddea87e8820615016878b183",
"orientation": "landscape",
"type": "hero",
"versions": {
"large-1024": {
"height": 213,
"mime": "image/png",
"type": "large-1024",
}
"width": 1024
}
}
这里的问题是图像对象中的散列。我不知道如何处理这个问题。哈希每个节日都有所不同。是否有可能在我的RealmObject中创建一个自定义的JSON解串器?
最后的代码示例是我目前的模型:
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迁移。
任何提示,欢迎,欢呼:)
更新
添加了图像模型:
public class Image extends RealmObject {
public String hash;
public String orientation;
public String type;
RealmList<Version> versions;
}
更新2
我尝试打电话realm.createOrUpdateAllFromJson前解析图像(Festival.class,回应);
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
我创建了清理破碎的JSON我从API获得的功能。这不是很好,但它现在工作。它删除了哈希和奇怪的版本,并将它们放在一个数组中。我确信它可以更有效地写入,但我只是去这个,所以我现在可以继续我的应用程序的其余部分。看到我自己的答案。
我自己的临时解决方案:
/**
* 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;
}
希望它可以帮助别人:)但肯定是不整齐。
由于关键是如何动态的,这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!
}
}
感谢您的回答。我如何将这与目前我解析json的方式结合起来?我应该@ignore图像,然后运行此代码添加图像后?或者我可以以某种方式实现这realm.createOrUpdateAllFromJson内? – Juxture
您需要其送入之前运行该代码'createOrUpdateAllFromJson' –
每个图像对象应分别作为对象被存储,同时通过键解析图像一个接一个。哈希本身也可以在对象中找到,毕竟,所以你不会丢失任何信息。 'createOrUpdateAll'需要一个数组,但这不是一个数组。 – EpicPandaForce
好的 - ------ – EpicPandaForce