英文:
Android Kotlin - save and retrieve JSONArray in SharedPreferences using gson or what ever
问题
I've already wasted many hours on this.
I need to store and retrieve val response = JSONArray(it)
in SharedPreferences.
So far I've only tried it with GSON
Attempt 1:
prefs.edit().putString("amz", response.toString()).apply()
val jsonPref = prefs.getString("amz", "")
val jArr: JsonArray = Gson().fromJson(jsonPref, JsonArray::class.java)
val title = jArr.getJSONObject(0).getString("title")
I get unresolved reference
on getJSONObject
even though it would work doing:
val title = response.getJSONObject(0).getString("title")
response
and jArr
look different.
response:
[{"asin":"B0015Z9KS2","title":"Eierbecher mit Stil ^^ 🐔🥚🐔","picurl":"/amzimg/B0015Z9KS2.jpg"},{"asin":"B002SQG4TU","title":"S**t happens... 😋😍😁","picurl":"/amzimg/B002SQG4TU.jpg"}]
jArr:
[{"asin":"B0015Z9KS2","title":"Eierbecher mit Stil ^^ 🐔🥚🐔","picurl":"/amzimg/B0015Z9KS2.jpg"},{"asin":"B002SQG4TU","title":"S**t happens... 😋😍😁","picurl":"/amzimg/B002SQG4TU.jpg"}]
So response
is escaped, jArr
not
Attempt 2:
prefs.edit().putString("amz", response.toString()).apply()
val jsonPref = prefs.getString("amz", "")
val jArr: JsonArray = JsonParser.parseString(jsonPref).asJsonArray
val title = jArr.getJSONObject(0).getString("title")
exactly the same issue as in attempt 1.
Attempt 3:
prefs.edit().putString("amz", Gson().toJson(response)).apply()
val jsonPref = prefs.getString("amz", "")
val jArr: JsonArray = Gson().fromJson(jsonPref, JsonArray::class.java)
Here I get
Expected a com.google.gson.JsonArray but was com.google.gson.JsonObject
on
val jArr: JsonArray = Gson().fromJson(jsonPref, JsonArray::class.java)
Attempt 4:
prefs.edit().putString("amz", Gson().toJson(response)).apply()
val jsonPref = prefs.getString("amz", "")
val jArr: JSONArray = Gson().fromJson(jsonPref, JSONArray::class.java)
note the difference between JsonArray
and JSONArray
and here I get this stupid nonsense when printing jArr:
["{nameValuePairs={asin=B0015Z9KS2, title=Eierbecher mit Stil ^^ 🐔🥚🐔, picurl=/amzimg/B0015Z9KS2.jpg}}","{nameValuePairs={asin=B002SQG4TU, title=S**t happens... 😋😍😁, picurl=/amzimg/B002SQG4TU.jpg}}"]
Please help!
英文:
I've already wasted many hours on this.
I need to store and retrieve val response = JSONArray(it)
in SharedPreferences.
So far I've only tried it with GSON
Attempt 1:
prefs.edit().putString("amz", response.toString()).apply()
val jsonPref = prefs.getString("amz", "")
val jArr: JsonArray = Gson().fromJson(jsonPref, JsonArray::class.java)
val title = jArr.getJSONObject(0).getString("title")
I get unresolved reference
on getJSONObject
even though it would work doing:
val title = response.getJSONObject(0).getString("title")
response
and jArr
look different.
response:
[{"asin":"B0015Z9KS2","title":"Eierbecher mit Stil ^^ 🐔🥚🐔","picurl":"\/amzimg\/B0015Z9KS2.jpg"},{"asin":"B002SQG4TU","title":"S**t happens... 😋😍😁","picurl":"\/amzimg\/B002SQG4TU.jpg"}]
jArr:
[{"asin":"B0015Z9KS2","title":"Eierbecher mit Stil ^^ 🐔🥚🐔","picurl":"/amzimg/B0015Z9KS2.jpg"},{"asin":"B002SQG4TU","title":"S**t happens... 😋😍😁","picurl":"/amzimg/B002SQG4TU.jpg"}]
So response
is escaped, jArr
not
Attempt 2:
prefs.edit().putString("amz", response.toString()).apply()
val jsonPref = prefs.getString("amz", "")
val jArr: JsonArray = JsonParser.parseString(jsonPref).asJsonArray
val title = jArr.getJSONObject(0).getString("title")
exactly the same issue as in attempt 1.
Attempt 3:
prefs.edit().putString("amz", Gson().toJson(response)).apply()
val jsonPref = prefs.getString("amz", "")
val jArr: JsonArray = Gson().fromJson(jsonPref, JsonArray::class.java)
Here I get
Expected a com.google.gson.JsonArray but was com.google.gson.JsonObject
on
val jArr: JsonArray = Gson().fromJson(jsonPref, JsonArray::class.java)
Attempt 4:
prefs.edit().putString("amz", Gson().toJson(response)).apply()
val jsonPref = prefs.getString("amz", "")
val jArr: JSONArray = Gson().fromJson(jsonPref, JSONArray::class.java)
note the difference between JsonArray
and JSONArray
and here I get this stupid nonsense when printing jArr:
["{nameValuePairs={asin=B0015Z9KS2, title=Eierbecher mit Stil ^^ 🐔🥚🐔, picurl=\/amzimg\/B0015Z9KS2.jpg}}","{nameValuePairs={asin=B002SQG4TU, title=S**t happens... 😋😍😁, picurl=\/amzimg\/B002SQG4TU.jpg}}"]
Please help!
答案1
得分: 1
这里的主要问题似乎是您混合了多个JSON库。 JSONArray
可能来自 JSON-java,而您的其他代码使用了 Gson。这也解释了您遇到的问题:
> 即使可以通过以下方式工作,我也会收到未解决的引用错误:
>
> kotlin > val title = response.getJSONObject(0).getString("title") >
jArr.getJSONObject(0)
不会工作,因为Gson具有 完全不同的API(您的IDE应该建议您现有的函数)。Gson的等效方法可能是 jArr.get(0).getAsJsonObject()
。
> response
和 jArr
看起来不同
这不应该有关系。唯一的区别似乎是 /
被转义了,这是可选的(还请参阅 JSON规范)。它不会改变所表示数据的含义,对于任何符合JSON规范的库来说,无论是 /
还是 \/
出现在JSON数据中都不应该有关系。
> kotlin > prefs.edit().putString("amz", Gson().toJson(response)).apply() > ... >
> 这里我得到了
> > 期望是 com.google.gson.JsonArray 但实际是 com.google.gson.JsonObject >
这很可能是“期望”的情况。response
的类型是 JSONArray
,但对于Gson来说是未知的,因为它来自不同的JSON库。因此,它将其视为普通类,没有内置适配器,并使用反射进行序列化。这导致生成一个包含 JSONArray
类的所有内部字段的JSON对象,而不是将其序列化为JSON数组。因此,当您尝试再次反序列化时,它失败,因为它被序列化为JSON对象,而不是JSON数组。
作为附注:一般来说,您应该避免依赖于Gson基于反射的序列化来处理第三方类,因为这样您会依赖于它们的实现细节,这些细节可能会在任何时候发生变化。
> 注意 JsonArray
和 JSONArray
之间的区别
> 并且在这里打印jArr时我得到了这种愚蠢的废话:
与前一个问题类似,只是现在您还在进行反序列化。
总之:不要混合不同的JSON库。要么坚持使用JSON-java,要么使用Gson,但不要两者兼用。如果确实有必要,您可以在代码的不同部分使用它们,只要在它们之间仅交换JSON数据即可,但要小心交换特定于库的对象。
英文:
The main problem here seems to be that you are mixing multiple JSON libraries. JSONArray
might be from JSON-java whereas your other code is using Gson. That also explains the issues you encountered:
> I get unresolved reference on getJSONObject even though it would work doing:
>
> kotlin
> val title = response.getJSONObject(0).getString("title")
>
jArr.getJSONObject(0)
won't work because Gson has a completely different API (your IDE should suggest you the existing functions). The Gson equivalent is probably jArr.get(0).getAsJsonObject()
.
> response
and jArr
look different
This should not matter. The only difference seems to be that /
is escaped, and that is optional (see also the JSON specification). It does not change the meaning of the represented data, and to any compliant JSON library it should not matter whether /
or \/
appears in the JSON data.
> kotlin
> prefs.edit().putString("amz", Gson().toJson(response)).apply()
> ...
>
> Here I get
>
> Expected a com.google.gson.JsonArray but was com.google.gson.JsonObject
>
This is most likely 'expected'. response
has the type JSONArray
which is unknown to Gson because it comes from a different JSON library. Therefore it treats it as regular class without built-in adapter and uses reflection to serialize it. This leads to a JSON object containing all the internal fields of the JSONArray
class instead of it being serialized as JSON array. Therefore when you try to deserialize it again it fails because it was serialized as JSON object not as JSON array.
As side note: In general you should avoid relying on Gson's reflection-based serialization for third-party classes because you then depend on their implementation details which could change at any point.
> note the difference between JsonArray
and JSONArray
> and here I get this stupid nonsense when printing jArr:
Similar to the previous one, except that you are now also deserializing it.
So in summary: Don't mix different JSON libraries. Either stick to JSON-java or to Gson, but not both. If really necessary you can use them in different parts of your code as long as you only exchange JSON data between them, but be careful with exchanging library-specific objects.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论