提问者:小点点

应用程序重新启动后重新初始化单例类


应用程序使用单例。 其中一个包含revofit客户端的实例。 另一个包含常量。

我可以在app preferences(在activity)中更改服务器URL,这样在应用程序重新启动后,我就可以用新的基本URL重新初始化revofit客户端。

在第一次启动之后,所有的单例和类都被初始化。 然后我在activity中更改URL并重新启动应用程序。 现在singletons不初始化并且包含旧常量。 如果我强制停止应用程序或附加调试器,这些单例程序会像预期的那样重新启动。

object ApiClass {

    private val gsonConverter: GsonConverter = GsonConverter()
    var gson: Gson
        private set
    var retrofit: Retrofit
        private set

    init {
        Timber.i("*** start ApiClass")

        val okHttpClient = OkHttpClient().newBuilder()
            .connectTimeout(60, TimeUnit.SECONDS)
            .readTimeout(60, TimeUnit.SECONDS)
            .writeTimeout(60, TimeUnit.SECONDS)
            .build()

        gson = GsonBuilder().setLenient().create()

        val url = "..." // Get a server URL from preferences.
        Timber.i("*** " + url)

        retrofit = Retrofit.Builder()
            .baseUrl(url)
            .client(okHttpClient)
            .addConverterFactory(GsonConverterFactory.create(gson))
            .build()
        ...
    }
}

/////////////

object ApiConst {

    init {
        Timber.i("*** start ApiConst")
    }

    const val SOME_TEXT = "text"
}

如何在不强制停止应用程序的情况下重新初始化单例程序?


共1个答案

匿名用户

多亏了@AL3C,我发现重新初始化singletons是没有用的。 我试着将一种形式的单例改变成另一种形式(比如在如何为改型2制作单例?):

class ApiClass {

    var gson: Gson private set
    lateinit var retrofit: Retrofit private set
    private val gsonConverter: GsonConverter = GsonConverter()
    private val okHttpClient: OkHttpClient

    init {
        Timber.i("*** start ApiClass")

        okHttpClient = OkHttpClient().newBuilder()
        ...
   }

    companion object {
        private var instance: ApiClass? = null

        fun getInstance(): ApiClass {
            if (instance == null) instance = ApiClass()
            return instance!!
        }
    }
}

但是调用APIClass.getInstance().reverfit并不能帮助我在重新启动后重新创建APIClass。 然后,我尝试在销毁应用程序之前更改revofit客户端中的一个基本URL(以便在重新启动后它将有一个新的URL)。 在阅读了Rovetfit-Change BaseUrl之后,我写道:

fun setBaseUrl(url: String) {
    retrofit = Retrofit.Builder()
        .baseUrl(url)
        .client(okHttpClient)
        .addConverterFactory(GsonConverterFactory.create(gson))
        .build()
}

然后,我能够从ondestroy中的首选项activity调用setbaseurl来更改revofit客户端。 它还帮助我继续使用新的URL请求应用程序,这样我就不必重新启动应用程序。