[JAVA] J'ai fait un adaptateur pour la classe de communication avec Retrofit2 + Rx2

introduction

Ce n'est encore qu'un mémo, alors je pense qu'il y a beaucoup de choses difficiles à comprendre. Je vous serais reconnaissant de bien vouloir faire une demande de modification le cas échéant.

Style d'écriture commun

C'est une prémisse que vous avez une connaissance générale de Retrofit et Rx. Si vous voulez en savoir plus, cet article, etc. sera très utile Implémentation rapide du client API avec Retrofit et Rx dans Kotlin


class MyApiDatasore {
   fun <T> createService(service: Class<T>) =
                Retrofit.Builder()
                        .baseUrl("url")
                        .addConverterFactory(JacksonConverterFactory.create(ObjectMapper()))
                        .addCallAdapterFactory(RxCallAdapterFactory.create())
                        .build()
                        .create(service)!!
}
interface MyApiService {
    @Get("hogehoge")
    fun fetchHogeHoge()

}

Votre interlocuteur


MyApiDatastore().createService(MyApiService::class.java)
                    .fetchHogeHoge()
                    .subscribeOn(Schedulers.newThread())       //Exécuter dans un fil d'arrière-plan
                    .observeOn(AndroidSchedulers.mainThread()) //Notifier le fil principal
                    .subscribe({
                        // onSuccess
                    }) { e ->
                        // onError

                    }

problème

C'est ennuyeux d'écrire ça à chaque fois.

  ...
  .subscribeOn(Schedulers.newThread())
  .observeOn(AndroidSchedulers.mainThread())

Mettons-le ensemble

Reportez-vous aux Articles ici, ou reportez-vous à la documentation et créez votre propre adaptateur personnalisé qui effectue les opérations ci-dessus à chaque fois. créé.

**
 * RxJava adapter for Retrofit.
 * Always `subscribeOn(Schedulers.newThread())`
 *        `observeOn(AndroidSchedulers.mainThread())`
 */
private class RxThreadingCallAdapterFactory : CallAdapter.Factory() {

    companion object {
        fun create(): CallAdapter.Factory = RxThreadingCallAdapterFactory()
    }

    //Toujours exécuter dans un nouveau thread
    private val original: RxJava2CallAdapterFactory = RxJava2CallAdapterFactory.createWithScheduler(Schedulers.newThread())

    override fun get(returnType: Type, annotations: Array<Annotation>, retrofit: Retrofit): CallAdapter<*, *> {
        // `original.get() == null` -> Retrofit throws IllegalArgumentException.
        return RxCallAdapterWrapper(original.get(returnType, annotations, retrofit)!!)
    }

    private class RxCallAdapterWrapper<R>(private val wrapped: CallAdapter<R, *>) : CallAdapter<R, Any> {
        override fun responseType(): Type = wrapped.responseType()

        //Toujours notifier le thread principal
        override fun adapt(call: Call<R>) = wrapped.adapt(call)
                .let {
                    when (it) {
                        is Completable -> {
                            it.observeOn(AndroidSchedulers.mainThread())
                        }
                        is Observable<*> -> {
                            it.observeOn(AndroidSchedulers.mainThread())
                        }
                        is Single<*> -> {
                            it.observeOn(AndroidSchedulers.mainThread())
                        }
                        is Flowable<*> -> {
                            it.observeOn(AndroidSchedulers.mainThread())
                        }
                        is Maybe<*> -> {
                            it.observeOn(AndroidSchedulers.mainThread())
                        }
                        else -> errorIfDebug()
                    }
                }!!
    }
}

Comment utiliser

En utilisant le service de mise à niveau comme indiqué ci-dessous, vous pouvez implémenter le processus pour qu'il s'exécute en arrière-plan et notifier le thread principal simplement en écrivant .subscribe à chaque fois.

      Retrofit.Builder()
              .baseUrl("url")
              .addConverterFactory(JacksonConverterFactory.create(ObjectMapper()))
              .addCallAdapterFactory(RxThreadingCallAdapterFactory.create()) //Utilisez un adaptateur personnalisé ici
              .build()
              .create(service)!!

Recommended Posts

J'ai fait un adaptateur pour la classe de communication avec Retrofit2 + Rx2
J'ai créé un serveur écologique avec scala
J'ai créé une application par moi-même! (Application de gestion de la lecture)
J'ai créé une application Android pour le service MiRm
J'ai créé un client API pour Nature Remo
J'ai créé une application Android qui GET avec HTTP
J'ai fait un interpréteur (compilateur?) Avec environ 80 lignes en Ruby.
Je veux pousser une application créée avec Rails 6 vers GitHub
J'ai mis à jour mon propre blackjack réalisé avec Ruby pour mon portfolio
J'ai créé une interface graphique avec Swing
J'ai essayé la communication UDP avec Java
J'ai fait une annotation en Java.
Exécuter des applications écrites en Java8 en Java6
J'ai fait une mort risquée avec Ruby
J'ai créé un plug-in pour IntelliJ IDEA
J'ai créé une application Janken avec kotlin
J'ai créé une application Janken avec Android