'Moshi parsing with InputStream
Assuming I need to parse a huge list of Items from a json asset file in Android with the format similar to below:
[
{
"id": 1,
"name: "Tom"
// other stuff to describe "Item"
}
]
For performance reason I want to avoid converting the whole file into a single String and parse it using moshi. I want instead to use stream and parse each item from json to Item and construct the list of items myself. With gson I think it can be done like this:
Gson gson = new GsonBuilder().create();
List<Item> items = new ArrayList<>();
// Read file in stream mode
try (JsonReader reader = new JsonReader(in)) {
reader.beginArray();
while (reader.hasNext()) {
// Read data into object model
Item item = gson.fromJson(reader, Item.class);
items.add(item);
}
} catch ...
}
I have been searching for a while but couldn't find Moshi's equivalent way for doing this. Any advice?
Thanks
Solution 1:[1]
Moshi uses Okio so you can do something like this for streaming json:
private val moshi by lazy {
Moshi.Builder().build()
}
private val adapter by lazy {
moshi.adapter(Layout::class.java)
}
fun AssetManager.layoutsFromJson(jsonFile: String): List<Layout> {
val layouts = mutableListOf<Layout>()
JsonReader.of(Okio.buffer(Okio.source(open(jsonFile)))).use { reader ->
reader.beginArray()
while (reader.hasNext()) {
adapter.fromJson(reader)?.let {
layouts.add(it)
}
}
}
return layouts
}
fun Fragment.layoutsAsset(jsonFile: String): List<Layout> {
return context?.assets?.layoutsFromJson(jsonFile) ?: emptyList()
}
Solution 2:[2]
Okio.buffer(Okio.source(open(jsonFile))) got deprecated, now there are extensions for this.
val inputStream = appContext.resources.openRawResource(R.raw.blah)
val adapter: JsonAdapter<MyDataClass> = moshi.adapter()
adapter.fromJson(inputStream.source().buffer())
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | manimaul |
| Solution 2 | George Shalvashvili |
