當我想在 viewModelScope 之外接收它時,為什么我的外部不可變 LiveData 值回傳 null?
正如您在 logcat 中看到的那樣,當我想在 viewModelScope 中接收它或第二次呼叫登錄函式時沒有問題。
這是我的視圖模型
class LoginViewModel(private val mainRepository: MainRepository) : ViewModel() {
private val _loginResponse = MutableLiveData<LoginResponse>()
val loginResponse: LiveData<LoginResponse> = _loginResponse
fun login(post: LoginBody) {
viewModelScope.launch {
try {
_loginResponse.value = mainRepository.loginPost(post = post)
Log.d(
LOGCAT,
"Login response : ${loginResponse.value?.data?.answerCount}"
)
} catch (e: Exception) {
Log.d(LOGCAT, "Login error: $e")
}
}
loginResponseOutsideOfTheViewModelScope()
}
fun loginResponseOutsideOfTheViewModelScope() {
Log.d(LOGCAT, "LoginResponseOutsideOfTheViewModelScope : ${loginResponse.value?.data?.answerCount}")
}
}
class LoginViewModelFactory(val app: GameApplication) :
ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
val retrofitService = app.retrofit
val context = app.applicationContext
val mainRepository = MainRepository(
retrofitService = retrofitService,
context = context
)
val viewModel = LoginViewModel(mainRepository)
return viewModel as T
}
}
這是我呼叫登錄功能的片段。
class FirstFragment : Fragment() {
private var _binding: FragmentFirstBinding? = null
private val binding
get() = _binding!!
private val viewModel: LoginViewModel by activityViewModels {
LoginViewModelFactory(
(activity?.application as GameApplication)
)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
_binding = FragmentFirstBinding.inflate(inflater)
binding.lifecycleOwner = this
binding.firstFragment = this
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val myPost = LoginBody(
deviceId = Settings.Secure.getString(
requireContext().contentResolver, Settings.Secure.ANDROID_ID
),
country = Locale.getDefault().country,
language = Locale.getDefault().language,
platform = Build.VERSION.SDK_INT.toString(),
version = BuildConfig.VERSION_NAME,
deviceModel = Build.MODEL
)
viewModel.login(myPost)
}
}
邏輯貓
2021-10-21 16:32:10.676 1520-1520/com.example.a4p1w D/DEBUG: LoginResponseOutsideOfTheViewModelScope : null
2021-10-21 16:32:12.354 1520-1520/com.example.a4p1w D/DEBUG: Login response : 12
uj5u.com熱心網友回復:
在login函式中,你有launch一個異步協程(它LiveData在記錄之前獲取一個值并設定它),然后你記錄 LiveData 的當前值。該協程需要時間,因此“當前值”日志陳述句首先運行(這就是它們按該順序列印的原因)。
您LiveData最初沒有值(您沒有將一個值傳遞給建構式):
private val _loginResponse = MutableLiveData<LoginResponse>()
所以loginResponse.value回傳null,直到您為其設定一個值(就像在您的協程中一樣)。這就是為什么當協程完成時它作業正常,之后每次閱讀它
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/330655.html
標籤:安卓 科特林 虚拟机 kotlin 协程 android-livedata
上一篇:如何將資料從AppCompatDialog傳遞到AppCompatActivity
下一篇:Dart物件比較。撲
