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

如何在onCreate中用Intent参数初始化AndroidViewModel并作为类val使用

解决方案:通过ViewModel Factory实现类级别val的AndroidViewModel初始化

要实现用Intent extras初始化AndroidViewModel并将其声明为类级别val,核心是借助自定义ViewModel Factory来传递初始化参数,避免使用lateinit var。以下是具体实现步骤和代码示例:

1. 定义带参数的AndroidViewModel

首先创建ShipmentViewModel,在构造函数中接收Application和从Intent extras获取的业务参数:

import android.app.Application
import androidx.lifecycle.AndroidViewModel

class ShipmentViewModel(
    application: Application,
    val shipmentId: String // 从Intent extras传入的参数
) : AndroidViewModel(application) {
    // 这里编写ViewModel的业务逻辑,比如数据请求、LiveData定义等
}

2. 实现自定义ViewModel Factory

创建Factory类,负责接收初始化参数并创建ViewModel实例:

import android.app.Application
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider

class ShipmentViewModelFactory(
    private val application: Application,
    private val shipmentId: String
) : ViewModelProvider.AndroidViewModelFactory(application) {
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        if (modelClass.isAssignableFrom(ShipmentViewModel::class.java)) {
            @Suppress("UNCHECKED_CAST")
            return ShipmentViewModel(application, shipmentId) as T
        }
        throw IllegalArgumentException("无法创建未知类型的ViewModel")
    }
}

3. 在Activity中初始化类级别val的ViewModel

使用by lazy委托延迟初始化ViewModel,确保在Intent可用时才完成实例化,同时直接声明为val:

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.lifecycle.ViewModelProvider

class ShipmentActivity : AppCompatActivity() {
    // 类级别val,通过lazy委托延迟初始化
    private val shipmentViewModel: ShipmentViewModel by lazy {
        // 从Intent extras中取出参数,这里做非空校验确保参数存在
        val shipmentId = intent.extras?.getString("SHIPMENT_ID") 
            ?: throw IllegalArgumentException("必须传入SHIPMENT_ID参数")
        
        ViewModelProvider(this, ShipmentViewModelFactory(application, shipmentId))
            .get(ShipmentViewModel::class.java)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_shipment)
        
        // 直接使用shipmentViewModel,比如观察LiveData
        shipmentViewModel.run {
            // 示例:viewModel.someLiveData.observe(this@ShipmentActivity) { ... }
        }
    }
}

关键说明

  • 借助by lazy,ViewModel会在首次被调用时才完成初始化,此时Intent已经可用,能正确获取extras参数。
  • 自定义Factory负责将参数传递给ViewModel构造函数,符合ViewModel的初始化规范,同时避免了lateinit var带来的空安全风险。
  • 对extras参数做非空校验,能提前发现参数缺失问题,避免后续运行时异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 19:12:06