0

我正在尝试将 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 放置了不同的示例。

4

2 回答 2

-1

不要尝试每次都返回 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这样的依赖注入库是一个更好的主意

于 2018-06-12T06:13:39.430 回答
-1

如果你想在 Kotlin 中制作单例,只需......使用对象,而不是类。

object Retrofit {
    val instance = ...
}

有关 Kotlin 中对象模式的更多示例,请参阅 # https://kotlinlang.org/docs/reference/object-declarations.html

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

于 2018-06-12T07:13:33.957 回答