Caused by: java.lang.IllegalStateException: Your activity is not yet attached to the Application instance. You can't request ViewModel before onCreate call.
class MyViewModelFactory constructor(private val repository: MainRepository) :
ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(MainViewModel::class.java)) {
return MainViewModel(repository) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}
接着把我们的工厂传给ViewModelProvider:
class MainActivity : ComponentActivity() {
private lateinit var viewModel: MainViewModel
private val repository: MainRepository = MainRepository()
private val viewModelFactory: MyViewModelFactory = MyViewModelFactory(repository)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = ViewModelProvider(this, viewModelFactory).get(MainViewModel::class.java)
}
}
class MyViewModelFactory constructor(private val repository: MainRepository) :
ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(MainViewModel::class.java)) {
return MainViewModel(repository) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}
class MainActivity : ComponentActivity() {
private val viewModel: MainViewModel by viewModels {
viewModelFactory
}
private val repository: MainRepository = MainRepository()
private val viewModelFactory: MyViewModelFactory = MyViewModelFactory(repository)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// use viewModel
}
}
工厂依然自己写, 简化了provider get的部分:
扩展方法, 隐含activity对象.
lazy规避了生命周期的问题, 只要使用ViewModel的地方不在onCreate之前就行.
ViewModel没有参数的时候更简单:
private val viewModel: MainViewModel by viewModels()
class MainRepository @Inject constructor(){}
@Singleton
class MyViewModelFactory @Inject constructor(private val repository: MainRepository) :
ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(MainViewModel::class.java)) {
return MainViewModel(repository) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}
class MainActivity : ComponentActivity() {
private val viewModel: MainViewModel by viewModels {
viewModelFactory
}
@Inject
lateinit var viewModelFactory: MyViewModelFactory
}
因为你用的是dagger, 你会需要在onCreate()里写类似这样的东西:
(applicationContext as MyApplication).appComponent.inject(this)
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
private val viewModel: MainViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// use viewModel
}
}