Как перевести клиент Retrofit с Kotlin на синглтон, сохраняющий Java? - PullRequest
0 голосов
/ 12 июня 2018

Я пытаюсь перевести клиентский код 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.

Ответы [ 2 ]

0 голосов
/ 12 июня 2018

Если вы хотите создать синглтон в Kotlin, просто ... используйте объект, а не класс.

object Retrofit {
    val instance = ...
}

см. # https://kotlinlang.org/docs/reference/object-declarations.html для большего примера шаблона объекта в Kotlin.

Но это все еще плохая практика.Гораздо лучше использовать DI-фреймворк, например, Kodein или Dagger2.

0 голосов
/ 12 июня 2018

Не пытайтесь каждый раз возвращать 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)
}

Лучше использовать зависимостьбиблиотека инъекций, такая как кинжал 2

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...