Как реализовать в Kotlin единый экземпляр Retrofit, который используется несколькими интерфейсами - PullRequest
0 голосов
/ 09 марта 2019

У меня есть login API, который возвращает клиенту authToken, и я сохраняю его в SharedPreferences. После login всем остальным API потребуется authToken из SharedPreferences. Итак, моя текущая реализация имеет 2 сервисных интерфейса для модернизации, как показано ниже:

UserDataService возвращает authToken:

interface UserDataService {

    @PUT("login")
    fun loginUser(@Body user: UserLoginRequest): Observable<Response<User>>

    companion object {

        // for Logging
        private val interceptor: HttpLoggingInterceptor = HttpLoggingInterceptor().apply {
            level = HttpLoggingInterceptor.Level.BODY
        }

        private val client: OkHttpClient = OkHttpClient.Builder().apply {
            addInterceptor(interceptor)
        }.build()

        val retrofit: UserDataService = Retrofit.Builder()
            .baseUrl("${URL}/users/")
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .addConverterFactory(MoshiConverterFactory.create())
            .client(client)
            .build()
            .create(UserDataService::class.java)
    }
}

PostDataService чтобы пользователи могли создавать посты в приложении, я использовал intercepter для добавления authToken во все вызовы API, связанные с Post.

interface PostDataService {

    @GET(".")
    fun getPosts(
        @Query(value = "offset") offset: Int = 0,
        @Query(value = "limit") limit: Int = 10,
        @Query(value = "subscribedOnly") subscribedOnly: Boolean = false
    ): Observable<List<Post>>

    companion object {

        // for Logging
        private val interceptor: HttpLoggingInterceptor = HttpLoggingInterceptor().apply {
            level = HttpLoggingInterceptor.Level.BODY
        }

        private val client = OkHttpClient.Builder().addInterceptor(object : Interceptor {
            @Throws(IOException::class)
            override fun intercept(chain: Interceptor.Chain): Response {
                val newRequest = chain.request().newBuilder()
                    .addHeader(
                        "Authorization",
                        "Bearer ${SharedPreferenceService.getToken(UrekaLiteApplication.context)}"
                    )
                    .addHeader("Content-Type", "application/json")
                    .build()
                return chain.proceed(newRequest)
            }
        }).addInterceptor(interceptor).build()

        val retrofit: PostDataService = Retrofit.Builder()
            .baseUrl("${URL}/post/")
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .addConverterFactory(MoshiConverterFactory.create())
            .client(client)
            .build()
            .create(PostDataService::class.java)
    }
}

Моя текущая реализация не выглядит оптимизированной для меня, потому что экземпляр модификации создается каждый раз, когда retrofit вызывается из любого из этих 2 интерфейсов. Кроме того, эти 2 интерфейса также разделены, и я имею в виду, что они не используют один и тот же экземпляр модернизации. Есть ли способ создать только один модифицированный синглтон один раз и использовать его среди нескольких интерфейсов модернизации?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...