簡體   English   中英

如何將Retrofit客戶端從Kotlin轉換為Java保留單例?

[英]How to translate Retrofit client from Kotlin to Java preserving singleton?

我正在嘗試將Java Retrofit Api客戶端代碼轉換為Kotlin。 這就是我們在Java中擁有的東西:

改造客戶端返回改造單例對象:

public class RetrofitClient {

    private static Retrofit retrofit = null;

    public static Retrofit getClient(String baseUrl) {
        if (retrofit==null) {
            retrofit = new Retrofit.Builder()
                    .baseUrl(baseUrl)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        }
        return retrofit;
    }
}

而使用上述改造對象的Api客戶端:

public class ApiUtils {

    public static final String BASE_URL = "https://api.stackexchange.com/2.2/";

    public static SOService getSOService() {
        return RetrofitClient.getClient(BASE_URL).create(SOService.class);
    }
}

問題在於,到目前為止,我在互聯網上看到的每個示例都使用同伴對象(其中的每個成員都是靜態對象),為什么我們的單例模式消失了? 為什么不使用對象而不是伴隨對象,該怎么做? 請參閱帶有Kotlin中的伴隨對象的示例:

interface WikiApiService {

    @GET("api.php")
    fun hitCountCheck(@Query("action") action: String): Observable<Model.Result>

    companion object {
        fun create(): WikiApiService {

            val retrofit = Retrofit.Builder()
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .addConverterFactory(GsonConverterFactory.create())
                    .baseUrl("https://en.wikipedia.org/w/")
                    .build()

            return retrofit.create(WikiApiService::class.java)
        }
    }

更不用說在同一類中完成此操作,使用伴隨對象將導致返回改造和WikiApiService的新對象。 我不同意。 請對這些示例進行任何說明。 也許我什么也沒得到,這就是為什么在我看來這是錯誤的,請原諒我為Java和Kotlin編寫了不同的示例。

不要嘗試每次都返回WikiApiService。

你可以創建一個類

class RetData {

    private lateinit var retrofit: Retrofit

    var wikiApiService: WikiApiService

    init {
        if (!::retrofit.isInitialized) {
            retrofit = Retrofit.Builder()
                    .baseUrl("https://api.stackexchange.com/2.2/")
                    .addConverterFactory(GsonConverterFactory.create())
                    .build()
        }
        wikiApiService = retrofit.create(WikiApiService::class.java)
    }
}

和訪問

fun test() {
    val retrofit = RetData()

    val apiService = retrofit.wikiApiService
    println(apiService)

    val apiService2 = retrofit.wikiApiService
    println(apiService2)

    val apiService3 = retrofit.wikiApiService
    println(apiService3)

    val apiService4 = retrofit.wikiApiService
    println(apiService4)
}

最好使用像dagger 2這樣的依賴注入庫

如果要在Kotlin中創建單例,只需...使用對象,而不是類。

object Retrofit {
    val instance = ...
}

見# https://kotlinlang.org/docs/reference/object-declarations.html用於科特林對象圖案的多個示例。

但這仍然是不好的做法。 使用DI框架要好得多,例如Kodein或Dagger2。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM