android 如何清除Activity中的Viewmodel状态

8yoxcaq7  于 2023-04-18  发布在  Android
关注(0)|答案(1)|浏览(183)

我在我的MVVM应用程序中有两个请求:

fun fetchStrings(lang: String, callBack: (res: JsonObject?) -> Unit) {
        job = CoroutineScope(Dispatchers.IO).launch {
            val array = JsonArray().apply { strings.forEach { item -> add(item) } }
            val jsonObject = JsonObject().apply {
                addProperty("lang", lang)
                add("ids", array)
            }
            val response = mainRepository.getStrings(jsonObject)
            withContext(Dispatchers.Main) {
                if (response.isSuccessful) {
                    callBack.invoke(response.body())
                } else {
                    callBack.invoke(null)
                }
            }
        }
    }

以及:

fun getUserFiles(requestBody: RequestBody? = null, callBack: (res: Any) -> Unit) {
        job = CoroutineScope(Dispatchers.IO).launch {
            val response = requestBody?.let { mainRepository.getUserFiles(it) }
            withContext(Dispatchers.Main) {
                if (response?.isSuccessful == true) {
                    callBack.invoke(response.body()!!)
                } else {
                    response?.message()?.let { callBack.invoke(it) }
                }
            }
        }
    }

它们都在一个视图模型中。这个视图模型使用mainRepository和这些方法:

class MainRepository constructor(private val retrofitService: RetrofitService) {
    suspend fun getUserFiles(requestBody: RequestBody) = retrofitService.getUserFiles(requestBody)
    suspend fun getStrings(jsonObject: JsonObject) = retrofitService.getStrings(jsonObject)
}

使用retrofitService:

companion object {
        var retrofitService: RetrofitService? = null
        fun getInstance(mint: Boolean): RetrofitService {
            var isMint = true
            val client = OkHttpClient.Builder()
                .connectTimeout(10, TimeUnit.MINUTES)
                .callTimeout(10, TimeUnit.MINUTES)
                .writeTimeout(10, TimeUnit.MINUTES)
                .readTimeout(10, TimeUnit.MINUTES)
                .connectionPool(ConnectionPool(0, 5, TimeUnit.SECONDS))
                .dispatcher(Dispatcher().apply {
                    maxRequests = 1
                })
                .protocols(listOf(Protocol.HTTP_1_1))
                .build()

            client.dispatcher.cancelAll()

            val retrofit = Retrofit.Builder()
                .baseUrl(if (mint) BuildConfig.MINT_URL else BuildConfig.API_URL)
                .client(client)
                .addConverterFactory(GsonConverterFactory.create())
                .build()
            retrofitService = retrofit.create(RetrofitService::class.java)

            return retrofitService!!
        }

    }

问题是,这些方法有两个不同的URL用于请求,由条件if (isMint) BuildConfig.MINT_URL else BuildConfig.API_URL管理,当我在activity中:

val retrofitService = RetrofitService.getInstance(false)
val mainRepository = MainRepository(retrofitService)
val viewVM =  ViewModelProvider(
this,
AppVMFactory(mainRepository)
)[RequestsCore::class.java]

在这里改变RetrofitService.getInstance(false) true/false,我看到这个值没有改变。我试图清除viewmodels:

viewModelStoreOwner.viewModelStore.clear()

但它没有帮助。我试图添加直接条件:

.baseUrl(if (mint) BuildConfig.MINT_URL else BuildConfig.API_URL)

这将取决于请求的url,但它也没有帮助.也尝试了这样的方式:

viewModelStoreOwner.viewModelStore.keys().forEach {
            viewModelStoreOwner.viewModelStore[it]?.viewModelScope?.coroutineContext?.cancel()
        }

我能看到的唯一方法是创建单独的Viewmodel,使用类似的存储库。也许我们有一些方法可以重置Viewmodel的所有值,在一个Viewmodelstoreowner的上下文中?

qnakjoqk

qnakjoqk1#

您的视图模型正常。问题位于RetrofitService概念中。
如果在同一个环境中有一些使用不同url的调用,请使用Dynamic URL而不是重新创建RetrofitService。

public interface RetrofitService {
    @GET
    getUserFiles(@Url url: String, requestBody: RequestBody): YourResponse1

    @GET
    getStrings(@Url url: String, jsonObject: JsonObject): YourResponse2
}

class MainRepository constructor(private val retrofitService: RetrofitService) {
    suspend fun getUserFiles(requestBody: RequestBody) : YourResponse1 {
      val url = BuildConfig.API_URL + "path" // Simplified explanation
      return retrofitService.getUserFiles(url, requestBody)
    }

    suspend fun getStrings(jsonObject: JsonObject) : YourResponse2 {
      val url = BuildConfig.MINT_URL + "path" // Simplified explanation
      return retrofitService.getStrings(url, jsonObject)
    }

}

This答案可能有助于路径生成。

相关问题