我试图在我的HomeFragment中从MutableLiveData<Resource<ObjectIWant>>
到var hereIwantTheObject : ObjectIWant
获得对象,显然使用资源类是推荐的方法,如果您使用协程和LiveData。问题是,我希望这个对象在我的变量上并从mutableelvedata中分离出来,当我尝试的时候它说变量还没有初始化。这里是我的课程和我所尝试的
ViewModel类:
class HomeFragmentViewModel : ViewModel() {
val mutableVar: MutableLiveData<Resource<ObjectIwant>> = MutableLiveData()
init {
getObjectIwantData()
}
fun getObjectIwantData() = viewModelScope.launch {
mutableVar.postValue(Resource.Loading())
val response = AppRepository().getObjectIwantDataInRepository()
mutableVar.postValue(handleResponse(response))
}
private fun handleResponse(response: Response<ObjectIwant>): Resource<ObjectIwant> {
if (response.isSuccessful) {
response.body()?.let { resultResponse ->
return Resource.Success(resultResponse)
}
}
return Resource.Error(response.message())
}
HomeFragment类和我试图得到的信息:
class HomeFragment : Fragment() {
lateinit var viewModel: HomeFragmentViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_home, container, false)
viewModel = ViewModelProvider(this).get(HomeFragmentViewModel::class.java)
binding.lifecycleOwner = this
var hereIwantTheObject: ObjectIwant? = null
viewModel.brastlewarkTownData.observe(viewLifecycleOwner, Observer { response ->
response.data?.let { brastlewarkTown ->
hereIwantTheObject = brastlewarkTown
}
})
Log.i(TAG, "onCreateView: ${hereIwantTheObject!!.name")
return binding.root
}
}
这里是Resource类:
sealed class Resource<T>(
val data: T? = null,
val message: String? = null
) {
class Success<T>(data: T) : Resource<T>(data)
class Error<T>(message: String, data: T? = null) : Resource<T>(data, message)
class Loading<T> : Resource<T>()
}
执行onCreateView()
时,会发生以下几件事:
- 本地
var hereIwantTheObject
用null
声明和初始化 - 注册
LiveData<Resource<ObjectIwant>>
对象的观察者 - 本地变量的值仍然是
null
,但是当写入Logcat 时,您承诺它不是 - 所以此时你的应用程序会崩溃…
null
。但是为什么hereIwantTheObject仍然是null
?这是因为任何LiveData
对象的观察结果只能在当前函数onCreateView()
执行完成后才能进入UI线程。
此时,局部变量将被丢弃,所以如果你想以后能够给它赋值,你需要把它变成一个属性:
private var hereIwantTheObject: String? = null
现在,如果您删除带有hereIwantTheObject局部声明的行,并将Log.i(...)
语句移动到LiveData
对象发生更改时执行的块中,则一切都将按预期工作
response.data?.let { brastlewarkTown ->
hereIwantTheObject = brastlewarkTown
Log.i(TAG, "onCreateView: ${hereIwantTheObject!!.name}")
}