【问题标题】:Getting "No virtual method getTag(Ljava/lang/String;)" error when calling suspended method using viewModelScope.launch inside ViewModel在 ViewModel 中使用 viewModelScope.launch 调用挂起的方法时出现“No virtual method getTag(Ljava/lang/String;)”错误
【发布时间】:2019-07-14 11:58:45
【问题描述】:

我正在尝试通过viewModelScope.launch() 调用暂停的方法,但一旦调用该方法,应用就会崩溃。

我应该指出我正在使用最新版本的 androidX 稳定库。 然而,对于 ViewModel 和 LiveData,我使用的是 2.2.0-alpha02 的 alpha 版本。 当然,Retrofit 版本是2.6.0,所以将其功能标记为暂停应该没问题。

此外,变量是使用 Koin 初始化的。

日志:

java.lang.NoSuchMethodError: No virtual method getTag(Ljava/lang/String;)Ljava/lang/Object; in class Landroidx/lifecycle/ViewModel; or its super classes (declaration of 'androidx.lifecycle.ViewModel' appears in /data/app/co.nilin.varabank-lUNWj0JGUm_fCoYkMmbbJg==/base.apk)
        at androidx.lifecycle.ViewModelKt.getViewModelScope(ViewModel.kt:36)
        at co.nilin.varabank.home.HomeViewModel.fetchRates(HomeViewModel.kt:18)
        at co.nilin.varabank.home.HomeActivity$init$2.onClick(HomeActivity.kt:27)
        at android.view.View.performClick(View.java:6597)
        at android.view.View.performClickInternal(View.java:6574)
        at android.view.View.access$3100(View.java:778)
        at android.view.View$PerformClick.run(View.java:25885)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

改造网络服务:

interface BankCalculatorWebService {
    @GET("auto/bank-gateway/general/{bank}/currencies")
    suspend fun fetchCurrencyRates(@Path("bank") bank: String): Response<CurrencyRateResponse>
}

存储库:

class BankCalculatorRepositoryImpl(
    private val webService: BankCalculatorWebService
) : BankCalculatorRepository {
    override suspend fun fetchRates(): List<CurrencyRateDTO> {
        val list = ArrayList<CurrencyRateDTO>()
        val response = webService.fetchCurrencyRates(Bank.getDefaultBank().swiftCode)
        response.ifSuccessful { response ->
            response.items.forEach {
                list.add(CurrencyRateDTO.fromCurrencyRate(it))
            }
        }
        return list
    }
}

查看模型:

class HomeViewModel(
    private val repository: BankCalculatorRepository
) : ViewModel() {
    val rates = MutableLiveData<List<CurrencyRateDTO>>()

    fun fetchRates() {
        viewModelScope.launch {
            val response = repository.fetchRates()
            rates.postValue(response)
        }
    }
}

活动内的代码

viewModel.rates.observe(this) {
    Toast.makeText(this, it.size, Toast.LENGTH_SHORT).show()
}

button.setOnClickListener {
    viewModel.fetchRates()
}

【问题讨论】:

  • Jetpack 库中的版本似乎不匹配
  • @EpicPandaForce 是的,看我的回答

标签: android kotlin androidx android-viewmodel kotlin-coroutines


【解决方案1】:

这是由于依赖于不同版本的 androidx.lifecycle.ViewModel 类污染了您的类路径(可能与 2.2.0 和 2.0.0 版本有关)。这通常是由于过时库的传递依赖。对我来说,这是导致它的 support-v4 库。

运行./gradlew app:dependencies 来查看你的树,然后寻找ViewModel 上的传递依赖。对于那些拉入旧版本的库,要么更新它们,要么为它们排除 ViewModel 依赖项:

implemenation ("com.<library>") {
    exclude group:'androidx.lifecycle', module:'lifecycle-viewmodel'
}

【讨论】:

    【解决方案2】:

    我也有同样的问题。我找不到任何解决方案,而不是自己实现 viewModelScope。您的 HomeViewModel 代码如下所示

     class HomeViewModel(
        private val repository: BankCalculatorRepository
    ) : ViewModel() {
    
    private val viewModelJob = SupervisorJob()
    protected val uiScope = CoroutineScope(Dispatchers.Main + viewModelJob)
    
    val rates = MutableLiveData<List<CurrencyRateDTO>>()
    
        fun fetchRates() {
            uiScope.launch {
                val response = repository.fetchRates()
                rates.postValue(response)
            }
        }
    
        /**
         * Cancel all coroutines when the ViewModel is cleared
         */
        override fun onCleared() {
            super.onCleared()
            uiScope.coroutineContext.cancelChildren()
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-26
      • 1970-01-01
      • 2018-01-16
      • 1970-01-01
      • 2019-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多