使用InputStream进行Moshi解析

5

假设我需要从 Android 上的一个类似以下格式的 json 资源文件中解析出大量的 Item

[
    {
        "id": 1,
        "name: "Tom"
        // other stuff to describe "Item"
    }
]

为了提高性能,我希望避免将整个文件转换为单个 String 并使用 moshi 解析它。我想要使用流,将每个项目从 json 解析到 Item 中,并自己构建项目列表。使用 gson,我认为可以这样做:
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 ...

我已经搜索了一段时间,但找不到Moshi的相应方法来做这件事。有什么建议吗?

谢谢

2个回答

3

Okio.buffer(Okio.source(open(jsonFile)))被弃用了,现在有相关扩展替代它。

val inputStream = appContext.resources.openRawResource(R.raw.blah)
val adapter: JsonAdapter<MyDataClass> = moshi.adapter()

adapter.fromJson(inputStream.source().buffer())

你在哪里看到Okio.buffer(Okio.source(open(jsonFile)))被弃用了?文档中有提到吗?实际上,你在哪里可以找到关于Okio 2.x的有用API文档? - Garret Wilson

2
Moshi使用Okio,因此您可以使用以下代码流式传输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()
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接