首页 > 解决方案 > 将数据传递到远程服务器

问题描述

使用 Kotlin、Retrofit 和 Coroutines,我定义了一个接口来从远程服务器获取数据,最重要的是,将选定的 RecyclerView 项目的 id 传递回服务器。

interface CourseService {
    @GET("/mobile/feed/course_data.php")
    suspend fun getCourseData(@Query("pathName") pathName: String): Response<List<Course>>
}

在这里,我从 MainFragment 的 RecyclerView 中获取所选项目的 id,并将其存储在“selectedItem”变量中。

override fun onPathItemClick(path: Path) {
    viewModel.selectedItem.value = path
    selectedItem= viewModel.selectedItem.value!!.path_id
    navController.navigate(R.id.action_mainFragment_to_courseFragment)
}

我将所选项目的值传递给 getCourseData() 函数

class CourseRepository(val app: Application) {

    val courseData = MutableLiveData<List<Course>>()

    init {
        CoroutineScope(Dispatchers.IO).launch {
            callWebService()
        }
    }

    @WorkerThread
    suspend fun callWebService() {
            val retrofit = Retrofit.Builder().baseUrl(WEB_SERVICE_URL).addConverterFactory(MoshiConverterFactory.create()).build()
            val service = retrofit.create(CourseService::class.java)
            val serviceData = service.getCourseData(selectedItem).body() ?: emptyList()
            courseData.postValue(serviceData)
    }
}

但是我没有得到任何结果,似乎传递给 getCourseData() 函数的值是空的,但是在检查日志时确实有一个值。

所以如果我在我的代码中的任何地方给它一个预定义的值,就像下面一样,一切都很好

    selectedItem= "MOB001"
    val serviceData = service.getCourseData(selectedItem).body() ?: emptyList()

但是,我不能在运行前给它一个固定值,因为当用户从 RecyclerView 中选择一个项目时会检索该值。

这些是我的多个日志:

2020-05-01 13:56:30.431 23843-23843/ I/mylog: Main Fragment before item click: selectedItem = 
2020-05-01 13:56:37.757 23843-23843/ I/mylog: Main Fragment after item click: selectedItem = WEB001
2020-05-01 13:56:37.763 23843-23843/ I/mylog: Course Fragment onCreateView(): selectedItem = WEB001
2020-05-01 13:56:37.772 23843-23901/ I/mylog: Course Fragment CourseRepository: selectedItem = WEB001

我该如何克服这个问题?

标签: androidkotlinretrofitretrofit2kotlin-coroutines

解决方案


你应该CourseRepositorycallWebService 你的ViewModel. 这是您的存储库:

class CourseRepository(val app: Application) {
    suspend fun callWebService(path: Path): List<Course> {
        return withContext(Dispatchers.IO) {
            val retrofit = Retrofit.Builder().baseUrl(WEB_SERVICE_URL).addConverterFactory(MoshiConverterFactory.create()).build()
            val service = retrofit.create(CourseService::class.java)
            service.getCourseData(path.path_id).body() ?: emptyList()
        }
    }
}

然后你应该在你的 ViewModel 中调用你的存储库函数,如下所示:

fun getCourseData(path: Path): LiveData<List<Course>> {
    val response = MutableLiveData<List<Course>>()
    viewModelScope.launch {
        response.postValue(repository.callWebService(path))
    }
    return response
}

然后在您获得有效价值时viewModel. getCourseData(path)从您的Activity或任何地方致电。FragmentPath

不要忘记包含implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0"到您的 gradle 文件中。


推荐阅读