Kotlin,使用协程进行改造的建议方法是什么

时间:2019-06-26 19:13:57

标签: retrofit2 kotlin-coroutines

在应用程序中,它将从多个端点获取数据以为调用方构造一个组合流,因此一个端点将有多个FetchRemoteDataCommand。喜欢

   val fetchers = getFetchers (...)  //returns  ArrayList<FetchRemoteDataCommand> with different endpoints

   for (f in fetchers) {
       f.doPost()
   }

当前,它不使用协程,而是根据回调onDataFetchComplete将结果传递回调用方。调用者必须管理每个提取程序的状态,才能最终将每个提取程序的所有结果组合在一起。

认为协程可能会帮助您进行管理。

如何使用等待所有提取程序完成其改造调用,然后根据所有提取程序的结果构建聚合流的协程,来做到这一点?

是否可以像这样完成

   runBlocking {
       for (f in fetchers) {
           launch { f.doPost() }
       }
   }

   // now all fetcher has finished
   var resultStream = ArrayList<T>()
   for (f in fetchers) {
       resultStream.add(f.dgetResult())
    }

还是其他更好的方法?

FetchRemoteDataCommand

    class FetchRemoteDataCommand<T>(val baseUrl: String,
                                    val path: String,
                                    var headers: HashMap<String, String>,
                                    var params: HashMap<String, String>,
                                    val body: okhttp3.RequestBody? = null,
                                    callback: ICallback<IData<T>>,
                                    var httpClient: OkHttpClient,
                                    POJOClassType: Class<T>) {

        private var fetchCompleteCallback: ICallback<IGenericData<T>> = callback
        val mPOJOClazz: Class<T> = POJOClassType

        var resultData: T? = null
        fun getResult(): T? {
            return resultData
        }

        suspend fun doPost() {
            val service = createRetrofitService(IRemoteDataRequest::class.java, baseUrl, httpClient)
            service.postForData(path, headers, params, body!!).enqueue(object : Callback<ResponseBody> {

                override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {
                    try {

                        val jsonString: String = response.body()?.string() ?: ""
                        resultData = try {
                            Gson().fromJson<T>(jsonString, mPOJOClazz)
                        } catch (e: Exception) {
                            null
                        }

                        val headerList  = response.headers()
                        val errorBodyString = response.errorBody()?.string()
                        val success = response.isSuccessful
                        val contentType = response.body()?.contentType()
                        val code = response.code() ?: -1
                        var message = response.message() ?: ""


                        Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()).execute {
                            fetchCompleteCallback.onDataFetchComplete(resultData, success, code, message, errorBodyString, contentType, headerList)
                        }
                    } finally {
                        response.body()?.close()
                    }
                }

                override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
                    Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()).execute {
                        fetchCompleteCallback.onDataFetchComplete(null, false, -1, t.message ?: "", null, null, null)
                    }
                }
            })

        }

        fun <T> createRetrofitService(clazz: Class<T>, endPoint: String, httpClient: OkHttpClient): T {

            val restAdapter = Retrofit.Builder()
                    .baseUrl(endPoint)
                    .addConverterFactory(GsonConverterFactory.create())
                    .client(httpClient)
                    .build()
            return restAdapter.create(clazz)
        }
    }


    interface IRemoteDataRequest {

        @POST
        fun postForData(@Url url: String,
                        @HeaderMap headers: Map<String, String>,
                        @QueryMap params: Map<String, String>?, @Body body: RequestBody): Call<ResponseBody>
    }

0 个答案:

没有答案