Retrofit2调用在viewModelScope中失败但在lifecycleScope中正常的问题求助
Retrofit2调用在viewModelScope中失败但在lifecycleScope中正常的问题求助
大家好,我正在做一个大学项目,开发一款模拟超市电商的Android应用。我用Retrofit2和Moshi对接产品数据库的REST API,所有业务逻辑都放在ViewModel里处理,但现在碰到了一个诡异的问题:
当我在viewModelScope.launch{ ... }代码块里发送GET请求时,Retrofit好像完全没有返回任何内容;可把一模一样的代码移到MainActivity里,用lifecycleScope.launch{ ... }运行就完全正常。
下面是我的相关代码:
ProductService接口
interface ProductService { @GET("product") suspend fun getAllProducts(): Response<List<Product>> @GET("product/{pId}") suspend fun getProductById(@Path("pId") pId: Int): Response<Product> @POST("product") suspend fun createNewProduct(@Body post: POST): POST }
Retrofit与Moshi配置的单例WPAPI
object WPAPI { val moshi: Moshi = Moshi.Builder() .add(com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory()) .build() val logging = HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BODY } val client = OkHttpClient.Builder() .addInterceptor(logging) .build() val retrofitService : ProductService by lazy { Retrofit.Builder() .baseUrl("http://[redacted]:8080/api/") .addConverterFactory(MoshiConverterFactory.create(moshi)) .client(client) .build() .create(ProductService::class.java) } }
ProductViewModel中的getAllProducts方法
fun getAllProducts() : LiveData<List<Product>> { val result = MutableLiveData<List<Product>>() viewModelScope.launch { val response: Response<List<Product>> = try { WPAPI.retrofitService.getAllProducts() } catch (e: IOException) { Log.e("ProductViewModel", "IOException", e) return@launch } catch (e: HttpException) { Log.e("ProductViewModel", "HttpException", e) return@launch } catch (e: Exception) { Log.wtf("ProductViewModel", "Exception", e) return@launch } if (response.isSuccessful && response.body() != null) { Log.i("ProductViewModel", "Response is good") result.postValue(response.body()!!) } } return result }
在MainActivity中调用ViewModel方法的方式
val productsDBList : List<Product> = viewModel.getAllProducts().value!!
我用调试器一步步走代码的时候,在ViewModel里刚执行到WPAPI.retrofitService.getAllProducts()这一行,就直接跳到了方法末尾的return result,整个过程LogCat里没有任何错误日志输出,最后因为上面代码里的!!运算符抛出了NullPointerException。
我本来怀疑是ViewModel的onCleared()方法被提前调用了,但重写这个方法后发现根本没触发。
对比之下,在MainActivity里用lifecycleScope的代码就完全正常:
lifecycleScope.launch { val response: Response<List<Product>> = try { WPAPI.retrofitService.getAllProducts() } catch (e: IOException) { Log.e("ProductViewModel", "IOException", e) return@launch } catch (e: HttpException) { Log.e("ProductViewModel", "HttpException", e) return@launch } catch (e: Exception) { Log.wtf("ProductViewModel", "Exception", e) return@launch } if (response.isSuccessful && response.body() != null) { Log.i("LifecycleScope", "Response is good") val pAdapter = ProductAdapter(response.body()!!) productsRecView.adapter = pAdapter productsRecView.layoutManager= LinearLayoutManager(this@MainActivity) } }
我感觉自己肯定漏了某个很基础的点,有没有大佬能帮我指个方向?
内容来源于stack exchange
相关产品推荐
相关产品推荐

