Reputation: 141
I am struggling to translate this retrofit class into Kotlin. It is basically a singleton that works as a client and I am not sure of my Kotlin implementation. UserAPI and ProfileAPI are just interfaces.
public class RetrofitService {
private static final String BASE_URL = "https://test.api.com/";
private ProfileAPI profileAPI;
private UserAPI userAPI;
private static RetrofitService INSTANCE;
/**
* Method that returns the instance
* @return
*/
public static RetrofitService getInstance() {
if (INSTANCE == null) {
INSTANCE = new RetrofitService();
}
return INSTANCE;
}
private RetrofitService() {
Retrofit mRetrofit = new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.baseUrl(BASE_URL)
.build();
profileAPI = mRetrofit.create(ProfileAPI.class);
UserAPI = mRetrofit.create(UserAPI.class);
}
/**
* Method that returns the API
* @return
*/
public ProfileAPI getProfileApi() {
return profileAPI;
}
/**
* Method that returns the API
* @return
*/
public UserAPI getUserApi() {
return userAPI;
}
}
And this is my Kotlin implementation. As I understand this, the init block will be executed first when the class is instantiated.
class RetrofitService private constructor() {
/**
* Method that returns the API
* @return
*/
private val profileApi: ProfileAPI
private val userAPI: UserAPI
companion object {
private const val BASE_URL = "https://test.api.com/"
private var INSTANCE: RetrofitService? = null
/**
* Method that returns the instance
* @return
*/
fun getInstance(): RetrofitService? {
if (INSTANCE == null) {
INSTANCE = RetrofitService()
}
return INSTANCE
}
}
init {
val mRetrofit = Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.baseUrl(BASE_URL)
.build()
profileApi = mRetrofit.create(ProfileAPI::class.java)
UserAPI = mRetrofit.create(UserAPI::class.java)
}
}
But something tells me this is not the right way or it can be done better. Is there anything I can improve here?
UPDATE!!!
Based on comments and answer I have this implementation now
object RetrofitService {
private const val BASE_URL = "https://test.api.com"
private fun retrofitService(): Retrofit {
return Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.baseUrl(BASE_URL)
.build()
}
val profileApi: ProfileAPI by lazy {
retrofitService().create(ProfileAPI::class.java)
}
val userApi: UserAPI by lazy {
retrofitService().create(UserAPI::class.java)
}
}
Then I would use it like this
RetrofitService.profileApi
Would that be alright?
Upvotes: 11
Views: 7906
Reputation: 5257
You could use something like:
object MyApi {
private const val BASE_URL = " https://www.MYAPI.com/"
private val moshi = Moshi.Builder()
.add(KotlinJsonAdapterFactory())
.build()
private val retrofit = Retrofit.Builder()
.addConverterFactory(MoshiConverterFactory.create(moshi))
.addCallAdapterFactory(CoroutineCallAdapterFactory())
.client(clientBuilder.build())
.baseUrl(BASE_URL)
.build()
val retrofitService: MyApiService by lazy {
retrofit().create(MyApiService::class.java)
}
//If you want more service just add more val such as
val otherService: MyOtherService by lazy {
retrofit().create(MyOtherService::class.java
}
}
//To use it you just need to do:
MyApi.retrofitService
MyApi.otherService
object ClassName
is a singleton it'll only instance it once and reuse for next callby lazy
using this keyword, your retrofitService
will only be initialised the first time you call and then you'll reuse that same value, for more details look hereUpvotes: 17
Reputation: 529
//try to adapt this code sample to your code
object RetrofitConfig {
// use lazy to insure that only one instance of retrofit will be used - no duplication
private val retrofit : Retrofit by lazy {
Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("put_your_url_here")
.build()
}
// here put your services interface if you have more
val movieService : MovieService by lazy {
retrofit.create(MovieService::class.java)
}
val showService : ShowService by lazy {
retrofit.create(ShowService::class.java)
}
}
Upvotes: 5