2017-06-20 169 views
1

每次我的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() 
     } 
    } 

但是,儘管如此,我需要定義AuthApiService的create()方法。

是否有任何一種方法實現了ApiFactory類到SubApi類,以便我不必在每個子類中定義create方法?

回答

3

一個簡單的辦法就是直接打電話給你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() 
2

您可以通過修改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) 
+2

我覺得沒有必要改變簽名。爲什麼不簡單地調用函數作爲'val authApiService = ApiFactory.createRetrofit ()'? – hotkey

+0

@hotkey你是對的,這應該可以正常工作,我只是Kotlin的新手 – ledniov