Home » Android » android – Retrofit 2.6.0: Custom Coroutines CallAdapterFactory

android – Retrofit 2.6.0: Custom Coroutines CallAdapterFactory

Posted by: admin June 15, 2020 Leave a comment

Questions:

I need to do custom error handling in my api and I wanted to use coroutines with the new version of Retrofit. Since we don’t have to use Deferred any longer, our own Jake Wharton wrote this on reddit a month ago

enter image description here

https://github.com/square/retrofit/blob/master/samples/src/main/java/com/example/retrofit/RxJavaObserveOnMainThread.java

But I’m having problems creating the CallAdapterFactory properly.

To be specific, I don’t understand: “Delegates to built-in factory and then wraps the value in sealed class”

Is there anyone already using this setup that can help?

Here’s the current code

sealed class Results<out T: Any> {
    class Success<out T: Any>(val response: T): Results<T>()
    class Failure(val message: String, val serverError: ServerError?): Results<Nothing>()
    object NetworkError: Results<Nothing>()
}


class ResultsCallAdapterFactory private constructor() : CallAdapter.Factory() {

    companion object {
        @JvmStatic
        fun create() = ResultsCallAdapterFactory()
    }

    override fun get(returnType: Type, annotations: Array<Annotation>, retrofit: Retrofit): CallAdapter<*, *>? {
        return try {
            val enclosedType = returnType as ParameterizedType
            val responseType = getParameterUpperBound(0, enclosedType)
            val rawResultType = getRawType(responseType)
            val delegate: CallAdapter<Any,Any> = retrofit.nextCallAdapter(this,returnType,annotations) as CallAdapter<Any,Any>
            if(rawResultType != Results::class.java)
                null
            else {
                object: CallAdapter<Any,Any>{
                    override fun adapt(call: Call<Any>): Any {
                         val response = delegate.adapt(call)
                        //What should happen here?
                        return response
                    }

                    override fun responseType(): Type {
                        return delegate.responseType()
                    }

                }
            }
        } catch (e: ClassCastException) {
            null
        }

    }
}
How to&Answers:

Update: The answer was moved to a similar question, you can find it here.