Каждый мой интерфейс API-интерфейса службы создает статический метод,
interface AuthApiService { @FormUrlEncoded @POST("api/auth/login") fun postLogin(@Field("username") username: String, @Field("password") password: String): io.reactivex.Observable<LoginApiResponse> companion object Factory { fun create(): AuthApiService { val gson = GsonBuilder().setLenient().create() val retrofit = Retrofit.Builder() .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create(gson)) .baseUrl("http:192.168.24.188:8080") .build() return retrofit.create(AuthApiService::class.java) } } } interface BBBApiService { companion object Factory { fun create(): BBBApiService { val gson = GsonBuilder().setLenient().create() val retrofit = Retrofit.Builder() .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create(gson)) .baseUrl("http:192.168.24.188:8080") .build() return retrofit.create(BBBApiService::class.java) } } }
Но я хочу определить метод create () только один раз.
Поэтому я сделал класс ApiFactory,
interface ApiFactory { companion object { inline fun <reified T>createRetrofit(): T { val gson = GsonBuilder().setLenient().create() val retrofit = Retrofit.Builder() .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create(gson)) .baseUrl("http://192.168.24.188:8080") .build() return retrofit.create(T::class.java) } } } interface AuthApiService { @FormUrlEncoded @POST("api/auth/login") fun postLogin(@Field("username") username: String, @Field("password") password: String): io.reactivex.Observable<LoginApiResponse> companion object Factory { fun create(): AuthApiService { return ApiFactory.createRetrofit() } }
Но, тем не менее, мне нужно определить метод create () в AuthApiService.
Есть ли способ реализовать класс ApiFactory для классов SubApi, так что мне не нужно определять метод create в каждом дочернем классе?
Простое решение – просто вызвать функцию вашего ApiFactory
напрямую:
val authApiService = ApiFactory.createRetrofit<AuthApiService>()
Но если вы хотите иметь возможность вызвать AuthApiService.create()
, вы можете определить интерфейс маркера, скажем, ApiFactoryClient<T>
, и пометить с ним пустой companion object
.
interface ApiFactoryClient<T> interface AuthApiService { /* ... */ companion object : ApiFactoryClient<AuthApiService> }
А затем создайте функцию расширения, которая работает с ApiFactoryClient<T>
:
inline fun <reified T> ApiFactoryClient<T>.create(): T = ApiFactory.createRetrofit<T>()
И использование будет:
val authApiService = AuthApiService.create()
Вы можете изменить свой ApiFactory
следующим образом:
interface ApiFactory { companion object { inline fun <reified T>createRetrofit(klass: KClass<T>): T { val gson = GsonBuilder().setLenient().create() val retrofit = Retrofit.Builder() .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create(gson)) .baseUrl("http://192.168.24.188:8080") .build() return retrofit.create(klass.java) } } }
Затем используйте его для создания различных экземпляров службы:
val authApiService = ApiFactory.createRetrofit(AuthApiService::class)