You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ViewModel中访问assets目录下JSON文件以加载RecyclerView?

解决ViewModel读取Assets中JSON数据的问题

核心问题

ViewModel不能直接持有Context(会导致内存泄漏,且ViewModelProvider默认要求空构造),直接传Context的方式本身就不符合ViewModel的设计规范,这也是你添加空构造后仍无法获取数据的原因——空构造下ViewModel拿不到AssetManager来读取JSON。

正确实现步骤

  1. 创建ViewModel工厂类,用来向ViewModel传递AssetManager(而非直接传Context)
  2. 在ViewModel中通过AssetManager读取JSON,并通过LiveData通知UI更新
  3. 在Activity中通过工厂类获取ViewModel,观察LiveData更新RecyclerView

代码示例

1. ViewModel工厂类

class MyViewModelFactory(private val assetManager: AssetManager) : ViewModelProvider.Factory {
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        if (modelClass.isAssignableFrom(MyViewModel::class.java)) {
            @Suppress("UNCHECKED_CAST")
            return MyViewModel(assetManager) as T
        }
        throw IllegalArgumentException("Unknown ViewModel class")
    }
}

2. ViewModel实现

class MyViewModel(private val assetManager: AssetManager) : ViewModel() {
    // 用LiveData持有数据,确保数据变化能通知UI
    private val _dataList = MutableLiveData<List<YourDataModel>>()
    val dataList: LiveData<List<YourDataModel>> get() = _dataList

    init {
        // 初始化时加载JSON数据
        loadJsonFromAssets()
    }

    private fun loadJsonFromAssets() {
        try {
            // 读取assets下的JSON文件
            assetManager.open("your_data.json").use { inputStream ->
                val jsonString = inputStream.bufferedReader().readText()
                // 解析JSON为数据模型列表(这里以Gson为例,你也可以用Moshi/Jackson)
                val dataArray = Gson().fromJson(jsonString, Array<YourDataModel>::class.java)
                _dataList.postValue(dataArray.toList())
            }
        } catch (e: IOException) {
            e.printStackTrace()
            // 处理文件读取失败的情况,比如给_dataList.postValue空列表或错误提示
        }
    }
}

3. Activity中初始化ViewModel并观察数据

class YourActivity : AppCompatActivity() {
    private lateinit var viewModel: MyViewModel
    private lateinit var adapter: YourRecyclerViewAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_your)

        // 初始化Adapter
        adapter = YourRecyclerViewAdapter()
        findViewById<RecyclerView>(R.id.recycler_view).apply {
            this.adapter = adapter
            layoutManager = LinearLayoutManager(this@YourActivity)
        }

        // 通过工厂类获取ViewModel
        val factory = MyViewModelFactory(assets)
        viewModel = ViewModelProvider(this, factory)[MyViewModel::class.java]

        // 观察LiveData,更新RecyclerView
        viewModel.dataList.observe(this) { dataList ->
            adapter.submitList(dataList) // 如果用ListAdapter,用submitList;普通Adapter则直接set数据并notify
        }
    }
}

排查要点

  • 确认JSON文件名正确(assets目录下直接写文件名,不要加assets/前缀)
  • 检查数据模型类的字段和JSON键名对应(大小写、名称一致,或用@SerializedName注解)
  • 确保LiveData的observe方法正确绑定了Activity的生命周期,数据加载完成后能触发UI更新

内容的提问来源于stack exchange,提问作者Dragamaroon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 15:45:21