如何从 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 保存屏幕所需的临时数据,但用户是否通过身份验证对整个应用程序很重要,而不仅仅是单个屏幕。因此,它应该存储在与整个应用程序一样长的地方,并且可以从任何地方访问,比如存储库。