如何在MutableStateFlow中正确使用密封类?解决密封类无法实例化的警告问题
如何在MutableStateFlow中正确使用密封类?
你遇到的这个警告「Sealed types cannot be instantiated」其实很好理解——密封类本身是不允许直接实例化的,它的设计目的就是让你只能通过它定义的子类(也就是你写的Loading、Success、Fail)来表示不同的状态,而不能直接创建LoadState()的实例。
之所以之前用MutableLiveData的时候没出问题,是因为你注释里的MutableLiveData<LoadState>()其实是创建了一个没有初始值的LiveData(默认值为null),但MutableStateFlow要求必须有一个非空的初始值,你直接写LoadState()就触发了密封类不能实例化的限制。
解决方法很简单,直接用密封类的子类作为StateFlow的初始值:
open class BaseViewModel: ViewModel() { val loadState by lazy { // 选择一个合理的初始状态,比如默认进入加载状态 MutableStateFlow<LoadState>(LoadState.Loading()) } }
后续更新状态的时候,同样发射密封类的子类实例即可:
如果是在主线程更新,可以直接赋值:
// 标记加载成功 loadState.value = LoadState.Success()
如果是在后台协程中,就用emit方法:
viewModelScope.launch { // 标记加载失败 loadState.emit(LoadState.Fail()) }
额外优化建议:
如果你的状态子类不需要携带任何额外数据(比如不需要传递加载结果、错误信息),可以把它们改成object单例,这样不用每次创建新实例,更高效简洁:
sealed class LoadState { object Loading : LoadState() object Success : LoadState() object Fail : LoadState() }
使用的时候直接写LoadState.Loading(不用加括号)就可以了:
val loadState by lazy { MutableStateFlow<LoadState>(LoadState.Loading) }
内容的提问来源于stack exchange,提问作者kokod21
相关产品推荐
相关产品推荐

