首页 > 解决方案 > 在 Kotlin 中改造单例

问题描述

我正在努力将这个改造类翻译成 Kotlin。它基本上是一个作为客户端工作的单例,我不确定我的 Kotlin 实现。UserAPI 和 ProfileAPI 只是接口。

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;
}

}

这是我的 Kotlin 实现。据我了解,在实例化类时将首先执行 init 块。

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)
}
}

但是有些事情告诉我这不是正确的方法,或者可以做得更好。这里有什么可以改进的吗?

更新!!!

根据评论和回答,我现在有了这个实现

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)
}
}

然后我会像这样使用它

RetrofitService.profileApi

这样可以吗?

标签: javaandroidkotlinsingletonretrofit2

解决方案


你可以使用类似的东西:

object MyApi {

    private const val BASE_URL = " https://www.MYAPI.com/"

    private val moshi = Moshi.Builder()
        .add(KotlinJsonAdapterFactory())
        .build()

    private fun retrofit(): Retrofit {
        return 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是一个单例,它只会实例化一次并重用于下一次调用
  • by lazy使用这个关键字,你retrofitService只会在你第一次调用时被初始化,然后你会重用相同的值,更多细节看这里

推荐阅读