如何在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
相关产品推荐
相关产品推荐

