fix(retrofit): fix base URL management and reinitialization

Refactor base URL handling to use a mutable `baseUrl` and reinitialize Retrofit instances on update.
This commit is contained in:
Peter Vacho 2024-12-24 00:25:36 +01:00
parent 916a42fb59
commit a4890a1bb3
Signed by: school
GPG key ID: 8CFC3837052871B4
2 changed files with 51 additions and 46 deletions

View file

@ -34,7 +34,7 @@ class ServerSettingsBarFragment : Fragment() {
val baseUrlInput = dialogView.findViewById<EditText>(R.id.baseUrlInput)
// Pre-fill current base URL
baseUrlInput.setText(RetrofitClient.getBaseUrl())
baseUrlInput.setText(RetrofitClient.getCurrentBaseUrl())
AlertDialog.Builder(requireContext())
.setTitle(R.string.server_settings)

View file

@ -15,58 +15,29 @@ import java.io.IOException
object RetrofitClient {
private const val DEFAULT_BASE_URL = "http://10.0.2.2:8000"
private lateinit var retrofitWithReachability: Retrofit
private lateinit var retrofitWithoutReachability: Retrofit
private var baseUrl: String = DEFAULT_BASE_URL
private lateinit var appContext: Context
val authService: AuthService by lazy {
retrofitWithReachability.create(AuthService::class.java)
}
private var retrofitWithReachability: Retrofit? = null
private var retrofitWithoutReachability: Retrofit? = null
val generalService: GeneralService by lazy {
retrofitWithReachability.create(GeneralService::class.java)
}
val authService: AuthService
get() = retrofitWithReachability!!.create(AuthService::class.java)
val generalService: GeneralService
get() = retrofitWithReachability!!.create(GeneralService::class.java)
/**
* Initializes the RetrofitClient with context and token manager
*/
fun initialize(context: Context) {
appContext = context
val baseUrl = getBaseUrl()
val apiReachabilityInterceptor = ApiReachabilityInterceptor(context)
val authInterceptor = AuthInterceptor(context)
// OkHttpClient with ApiReachabilityInterceptor
val okHttpClientWithReachability = OkHttpClient.Builder()
.addInterceptor(apiReachabilityInterceptor)
.addInterceptor(authInterceptor)
.build()
// OkHttpClient without ApiReachabilityInterceptor
val okHttpClientWithoutReachability = OkHttpClient.Builder()
.addInterceptor(authInterceptor)
.build()
retrofitWithReachability = Retrofit.Builder()
.baseUrl(baseUrl)
.client(okHttpClientWithReachability)
.addConverterFactory(GsonConverterFactory.create())
.build()
retrofitWithoutReachability = Retrofit.Builder()
.baseUrl(baseUrl)
.client(okHttpClientWithoutReachability)
.addConverterFactory(GsonConverterFactory.create())
.build()
baseUrl = getBaseUrl()
resetRetrofitInstances()
}
/**
* Get the base api url that's currently in-use.
* Get the base api url that this client is currently using.
*/
fun getBaseUrl(): String {
val sharedPreferences = appContext.getSharedPreferences("app_settings", Context.MODE_PRIVATE)
return sharedPreferences.getString("base_url", DEFAULT_BASE_URL) ?: DEFAULT_BASE_URL
fun getCurrentBaseUrl(): String {
return baseUrl
}
/**
@ -75,9 +46,43 @@ object RetrofitClient {
* Note: This change will persist throughout restarts.
*/
fun updateBaseUrl(newBaseUrl: String) {
baseUrl = newBaseUrl
saveBaseUrl(newBaseUrl)
resetRetrofitInstances()
}
private fun resetRetrofitInstances() {
retrofitWithReachability = buildRetrofit(baseUrl, withReachability = true)
retrofitWithoutReachability = buildRetrofit(baseUrl, withReachability = false)
}
private fun buildRetrofit(baseUrl: String, withReachability: Boolean): Retrofit {
val okHttpClient = OkHttpClient.Builder()
if (withReachability) {
okHttpClient.addInterceptor(ApiReachabilityInterceptor(appContext))
}
okHttpClient.addInterceptor(AuthInterceptor(appContext))
return Retrofit.Builder()
.baseUrl(baseUrl)
.client(okHttpClient.build())
.addConverterFactory(GsonConverterFactory.create())
.build()
}
/**
* Get the base api url from the shared preferences persistent storage.
*/
private fun getBaseUrl(): String {
val sharedPreferences = appContext.getSharedPreferences("app_settings", Context.MODE_PRIVATE)
return sharedPreferences.getString("base_url", DEFAULT_BASE_URL) ?: DEFAULT_BASE_URL
}
/**
* Save the base api url into shared preferences persistent storage.
*/
private fun saveBaseUrl(newBaseUrl: String) {
val sharedPreferences = appContext.getSharedPreferences("app_settings", Context.MODE_PRIVATE)
sharedPreferences.edit().putString("base_url", newBaseUrl).apply()
initialize(appContext) // Reinitialize with updated URL
}
/**
@ -87,7 +92,7 @@ object RetrofitClient {
suspend fun performPingWithoutReachabilityCheck(): IOException? {
val responseBody: ResponseBody
try {
responseBody = retrofitWithoutReachability.create(GeneralService::class.java).ping()
responseBody = retrofitWithoutReachability!!.create(GeneralService::class.java).ping()
} catch (e: IOException) {
return e
}
@ -112,7 +117,7 @@ object RetrofitClient {
// If api was unreachable, our interceptor will give us a 503 response
val responseBody: ResponseBody
try {
responseBody = retrofitWithReachability.create(GeneralService::class.java).ping()
responseBody = retrofitWithReachability!!.create(GeneralService::class.java).ping()
} catch (e: HttpException) {
if (e.code() == 503) {
return false