如何从 viewModelScope 获取响应变量 Android
How to get response variable from viewModelScope Android
在我的 Android 项目中,我需要在另一个片段中使用我的视图模型的响应之一。但每当我尝试获取该值时,它始终为空。我试图从它自己的带有 livedata 的片段中获取它并且它有效!但是另一个片段就不一样了。这是我的具有响应的视图模型代码;
package com.tolgahantutar.bexworkfloww.ui.auth
import android.content.Intent
import android.view.View
import android.widget.Toast
import androidx.hilt.lifecycle.ViewModelInject
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.tolgahantutar.bexworkfloww.data.network.repositories.AuthorizeSessionRepository
import com.tolgahantutar.bexworkfloww.data.network.repositories.GetDomainRepository
import com.tolgahantutar.bexworkfloww.data.network.repositories.GetUserRepository
import com.tolgahantutar.bexworkfloww.data.network.responses.GetUserResponse
import com.tolgahantutar.bexworkfloww.ui.home.HomeActivity
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class AuthViewModel @ViewModelInject constructor (
private val authorizeSessionRepository: AuthorizeSessionRepository,
private val getDomainRepository: GetDomainRepository,
private val getUserRepository: GetUserRepository
):ViewModel() {
var userName :String?=null
var password: String ? = null
val isLoading = MutableLiveData<Boolean>()
private val location = "bexfatest.saasteknoloji.com"
val isSuccessfull = MutableLiveData<Boolean>()
var getUserResponseMutable = MutableLiveData<GetUserResponse>()
fun onClickUserLogin(view: View){
val sessionID = 0
val authorityID = 0
val loginType = "System"
viewModelScope.launch {
if(!(userName==null||password==null)){
isLoading.value = true
val authResponse = userLogin(sessionID,authorityID,userName!!,password!!,loginType)
if(authResponse.Result){
isLoading.value=false
val domainResponse=getDomain(location)
**`val getUserResponse`** = getUser(authResponse.authorizeSessionModel!!.ID,"Bearer "+domainResponse.getDomainModel.ApiKey)
if (getUserResponse.result){
isSuccessfull.value=true
getUserResponseMutable.value=getUserResponse
}
//Toast.makeText(view.context, "Login Successfull", Toast.LENGTH_LONG).show()
val intent = Intent(view.context,HomeActivity::class.java)
view.context.startActivity(intent)
}else{
isLoading.value=false
Toast.makeText(view.context, "Login Failed!!", Toast.LENGTH_LONG).show()
}
}
else{
Toast.makeText(view.context, "Kullanıcı adı ve şifre boş bırakılamaz!!", Toast.LENGTH_SHORT).show()
}
}
}
suspend fun userLogin(
SessionID : Int,
AuthorityID: Int,
UserName: String,
Password : String,
LoginType: String
)= withContext(Dispatchers.IO){authorizeSessionRepository.userLogin(SessionID, AuthorityID, UserName, Password, LoginType)}
suspend fun getUser(
id: Int,
authorization : String
)= withContext(Dispatchers.Main){getUserRepository.getUser(id,authorization)}
suspend fun getDomain(
Location: String
)= withContext(Dispatchers.IO){getDomainRepository.getDomain(Location)}
}
我需要像这样在我的地址簿片段中获取 getUserResponse 变量;
package com.tolgahantutar.bexworkfloww.ui.addressbook
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer
import com.tolgahantutar.bexworkfloww.R
import com.tolgahantutar.bexworkfloww.ui.auth.AuthViewModel
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class AdressBookFragment : Fragment() {
private val addressBookViewModel : AdressBookViewModel by viewModels()
private val authViewModel : AuthViewModel by viewModels()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.adress_book_fragment, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
//addressBookViewModel.getContact(2,authViewModel.userResponseDelegate!!.getUserValue.apiKey)
authViewModel.getUserResponseMutable.observe(viewLifecycleOwner, Observer {
if (it.result){
Toast.makeText(requireContext(), "asdadasd", Toast.LENGTH_SHORT).show()
}
})
addressBookViewModel.isSuccessfull.observe(viewLifecycleOwner, Observer {
if (it){
Toast.makeText(requireContext(), "ContactList Get Successfully", Toast.LENGTH_SHORT).show()
}
})
}
}
但 observe 始终为 null 我怎样才能在我的 AddressBookFragment 中获取 getUserResponse ??
private val authViewModel : AuthViewModel by viewModels()
等同于
private val viewModel by lazy {
ViewModelProvider(this).get(AuthViewModel::class.java)
}
所以你可以看到 this
被传递为 viewModelStoreOwner
。
因为我猜你在你的另一个片段中确实使用 AdressBookFragment
作为 viewModelStoreOwner
你正在这个片段中创建一个新的 viewmodel
。
您可能需要一个共享的视图模型,您可以在使用时获得该视图模型
private val viewModel by lazy {
ViewModelProvider(requireActivity()).get(AuthViewModel::class.java)
}
在两个片段中
当您离开 AuthFragment
(我假设您有)时,AuthViewModel
很可能会被破坏,因此您的 AdressBookFragment
正在获取 ViewModel 的一个新实例,它不会'保留上一屏幕的任何数据。
我建议您将 AuthViewModel
的结果存储到存储库或其他一些全局状态对象中,然后从那里检索它。
ViewModel 保存屏幕所需的临时数据,但用户是否通过身份验证对整个应用程序很重要,而不仅仅是单个屏幕。因此,它应该存储在与整个应用程序一样长的地方,并且可以从任何地方访问,比如存储库。
在我的 Android 项目中,我需要在另一个片段中使用我的视图模型的响应之一。但每当我尝试获取该值时,它始终为空。我试图从它自己的带有 livedata 的片段中获取它并且它有效!但是另一个片段就不一样了。这是我的具有响应的视图模型代码;
package com.tolgahantutar.bexworkfloww.ui.auth
import android.content.Intent
import android.view.View
import android.widget.Toast
import androidx.hilt.lifecycle.ViewModelInject
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.tolgahantutar.bexworkfloww.data.network.repositories.AuthorizeSessionRepository
import com.tolgahantutar.bexworkfloww.data.network.repositories.GetDomainRepository
import com.tolgahantutar.bexworkfloww.data.network.repositories.GetUserRepository
import com.tolgahantutar.bexworkfloww.data.network.responses.GetUserResponse
import com.tolgahantutar.bexworkfloww.ui.home.HomeActivity
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class AuthViewModel @ViewModelInject constructor (
private val authorizeSessionRepository: AuthorizeSessionRepository,
private val getDomainRepository: GetDomainRepository,
private val getUserRepository: GetUserRepository
):ViewModel() {
var userName :String?=null
var password: String ? = null
val isLoading = MutableLiveData<Boolean>()
private val location = "bexfatest.saasteknoloji.com"
val isSuccessfull = MutableLiveData<Boolean>()
var getUserResponseMutable = MutableLiveData<GetUserResponse>()
fun onClickUserLogin(view: View){
val sessionID = 0
val authorityID = 0
val loginType = "System"
viewModelScope.launch {
if(!(userName==null||password==null)){
isLoading.value = true
val authResponse = userLogin(sessionID,authorityID,userName!!,password!!,loginType)
if(authResponse.Result){
isLoading.value=false
val domainResponse=getDomain(location)
**`val getUserResponse`** = getUser(authResponse.authorizeSessionModel!!.ID,"Bearer "+domainResponse.getDomainModel.ApiKey)
if (getUserResponse.result){
isSuccessfull.value=true
getUserResponseMutable.value=getUserResponse
}
//Toast.makeText(view.context, "Login Successfull", Toast.LENGTH_LONG).show()
val intent = Intent(view.context,HomeActivity::class.java)
view.context.startActivity(intent)
}else{
isLoading.value=false
Toast.makeText(view.context, "Login Failed!!", Toast.LENGTH_LONG).show()
}
}
else{
Toast.makeText(view.context, "Kullanıcı adı ve şifre boş bırakılamaz!!", Toast.LENGTH_SHORT).show()
}
}
}
suspend fun userLogin(
SessionID : Int,
AuthorityID: Int,
UserName: String,
Password : String,
LoginType: String
)= withContext(Dispatchers.IO){authorizeSessionRepository.userLogin(SessionID, AuthorityID, UserName, Password, LoginType)}
suspend fun getUser(
id: Int,
authorization : String
)= withContext(Dispatchers.Main){getUserRepository.getUser(id,authorization)}
suspend fun getDomain(
Location: String
)= withContext(Dispatchers.IO){getDomainRepository.getDomain(Location)}
}
我需要像这样在我的地址簿片段中获取 getUserResponse 变量;
package com.tolgahantutar.bexworkfloww.ui.addressbook
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer
import com.tolgahantutar.bexworkfloww.R
import com.tolgahantutar.bexworkfloww.ui.auth.AuthViewModel
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class AdressBookFragment : Fragment() {
private val addressBookViewModel : AdressBookViewModel by viewModels()
private val authViewModel : AuthViewModel by viewModels()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.adress_book_fragment, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
//addressBookViewModel.getContact(2,authViewModel.userResponseDelegate!!.getUserValue.apiKey)
authViewModel.getUserResponseMutable.observe(viewLifecycleOwner, Observer {
if (it.result){
Toast.makeText(requireContext(), "asdadasd", Toast.LENGTH_SHORT).show()
}
})
addressBookViewModel.isSuccessfull.observe(viewLifecycleOwner, Observer {
if (it){
Toast.makeText(requireContext(), "ContactList Get Successfully", Toast.LENGTH_SHORT).show()
}
})
}
}
但 observe 始终为 null 我怎样才能在我的 AddressBookFragment 中获取 getUserResponse ??
private val authViewModel : AuthViewModel by viewModels()
等同于
private val viewModel by lazy {
ViewModelProvider(this).get(AuthViewModel::class.java)
}
所以你可以看到 this
被传递为 viewModelStoreOwner
。
因为我猜你在你的另一个片段中确实使用 AdressBookFragment
作为 viewModelStoreOwner
你正在这个片段中创建一个新的 viewmodel
。
您可能需要一个共享的视图模型,您可以在使用时获得该视图模型
private val viewModel by lazy {
ViewModelProvider(requireActivity()).get(AuthViewModel::class.java)
}
在两个片段中
当您离开 AuthFragment
(我假设您有)时,AuthViewModel
很可能会被破坏,因此您的 AdressBookFragment
正在获取 ViewModel 的一个新实例,它不会'保留上一屏幕的任何数据。
我建议您将 AuthViewModel
的结果存储到存储库或其他一些全局状态对象中,然后从那里检索它。
ViewModel 保存屏幕所需的临时数据,但用户是否通过身份验证对整个应用程序很重要,而不仅仅是单个屏幕。因此,它应该存储在与整个应用程序一样长的地方,并且可以从任何地方访问,比如存储库。