android 在初始化块中成功引用视图模型范围的视图模型协同程序中,注入变量仅为空

u1ehiz5o  于 2023-03-21  发布在  Android
关注(0)|答案(1)|浏览(104)

我遇到了一个非常奇怪的问题,我试图使用一个干净的体系结构样式的存储库对象在ViewModel中运行一个API调用,我能够在viewModelScope协同程序中访问init块中的repo对象
我有一个简单的解决方法;我只是不从init块调用函数,而是公开一个公共函数并从片段中调用它;所以我有一个解决方案,但这是一个有趣的问题。

@HiltViewModel
class MainViewModel @Inject constructor(repo: JobsRepository) : ViewModel(){

    @Inject lateinit var repo : JobsRepository
    lateinit var jobDao: JobDao

    val jobsListUpdate: MutableLiveData<Resource<JobsResponse>> = MutableLiveData()
    var jobsListResponse: JobsResponse? = null
    init {
       jobDao = repo.getDao()
      // getJobsList()
        viewModelScope.launch {
            jobsListUpdate.postValue(Resource.Loading())
            val response = repo.getAllJobsByAPI()
            jobsListUpdate.postValue(handleBreakingNewsResponse(response))
        }
    }

上面的代码可以工作,但是当我从一个非挂起的函数中调用它时,问题就出现了。

@HiltViewModel
class MainViewModel @Inject constructor(repo: JobsRepository) : ViewModel(){

    @Inject lateinit var repo : JobsRepository
    lateinit var jobDao: JobDao
    
    val jobsListUpdate: MutableLiveData<Resource<JobsResponse>> = MutableLiveData()
    var jobsListResponse: JobsResponse? = null
    init {
        
       jobDao = repo.getDao() 
       getJobsList()
    }

    fun getJobsList() {
        viewModelScope.launch {
            getJobsListFromApi()
        }
    }

    private suspend fun getJobsListFromApi() {
        jobsListUpdate.postValue(Resource.Loading())
        val response = repo.getAllJobsByAPI()
        jobsListUpdate.postValue(handleBreakingNewsResponse(response))
    }

这几乎就像repo对象在代码流中的其他地方被取消一样,比如在导航片段附加到其他地方之后。
不同之处肯定是suspend关键字。我会说这是一个竞态条件,但不寻常的是,对repo的引用在它有值后变为null。
有什么想法吗?还有什么是有用的添加到这个职位?

oaxa6hgo

oaxa6hgo1#

我认为你真实的问题是你在同一件事情上同时使用了构造函数注入和字段注入。我很惊讶这甚至编译了tbh。试着把它改为:

@HiltViewModel
class MainViewModel 
@Inject constructor(
  private val repo: JobsRepository
) : ViewModel(){
    val jobsListUpdate: MutableLiveData<Resource<JobsResponse>> = MutableLiveData()

    init {
       getJobsList()
    }

    fun getJobsList() {
        viewModelScope.launch {
            getJobsListFromApi()
        }
    }

    private suspend fun getJobsListFromApi() {
        jobsListUpdate.postValue(Resource.Loading())
        val response = repo.getAllJobsByAPI()
        jobsListUpdate.postValue(handleBreakingNewsResponse(response))
    }
}

我猜您所看到的是由上述问题引起的,实际上与挂起函数无关。

相关问题