Reputation: 324
I need to pass the Application Context to an object. This is to call a function to intercept in the okhttpClient, my connection service. I'am using an object class to build the connection to the server with retrofit and an external interface with my services.
object DfreeApiService {
private lateinit var interceptor: HttpLoggingInterceptor
private lateinit var okHttpClient: OkHttpClient
private lateinit var networkConnectivityInterceptor: NetworkConnectivityInterceptor
val client: Retrofit
get() {
networkConnectivityInterceptor= NetworkConnectivityInterceptor() //cannot pass the context here
interceptor = HttpLoggingInterceptor()
interceptor.level = HttpLoggingInterceptor.Level.BODY
okHttpClient= OkHttpClient.Builder()
// .addInterceptor(networkConnectivityInterceptor)
.addInterceptor(interceptor)
.connectionSpecs(
Arrays.asList(ConnectionSpec.MODERN_TLS, ConnectionSpec.CLEARTEXT)
)
.followRedirects(true)
.followSslRedirects(true)
.retryOnConnectionFailure(true)
.connectTimeout(20, TimeUnit.SECONDS)
.readTimeout(20, TimeUnit.SECONDS)
.writeTimeout(20, TimeUnit.SECONDS)
.cache(null)
.build()
val retrofit: Retrofit =Retrofit.Builder()
.client(okHttpClient)
.baseUrl("http://example:2000/")
.addConverterFactory(GsonConverterFactory.create())
.build()
return retrofit
}
}
And in the following code is my interface:
interface AuthenticationApi {
@POST("ws/login")
suspend fun login(@Body userInfo: UserInfo): Response<UserReponse>
@POST("ws/register")
suspend fun register(@Body userInfo: UserRegister): Response<UserReponse>
@POST("ws/pw_recover")
suspend fun pw_recover(@Body email: String): Response<BaseResponse>
@POST("ws/login")
suspend fun loginGoogle(@Body user: GoogleUser) : Response<UserReponse>
companion object{
operator fun invoke():AuthenticationApi{
return DfreeApiService.client.create(AuthenticationApi::class.java)
}
}
}
I'am using mvvm and kodein. Without the internet interceptor the app crashes when there is no internet. My interceptor:
class NetworkConnectivityInterceptor(
context: Context
) : Interceptor {
private val applicationContext = context
@RequiresApi(Build.VERSION_CODES.M)
override fun intercept(chain: Interceptor.Chain): Response {
if (!isInternetAvailable())
throw NoInternetException("Make sure you have an active data connection")
return chain.proceed(chain.request())
}
@RequiresApi(Build.VERSION_CODES.M)
private fun isInternetAvailable(): Boolean {
var result = false
val connectivityManager =
applicationContext.getSystemService(Application.CONNECTIVITY_SERVICE) as ConnectivityManager?
connectivityManager?.let {
it.getNetworkCapabilities(connectivityManager.activeNetwork)?.apply {
result = when {
hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
else -> false
}
}
}
return result
}
}
Thanks for your attention
Upvotes: 2
Views: 4603
Reputation: 324
In the mainActivity:
class ExampleApplication : Application(), KodeinAware {
lateinit var context: Context
override val kodein = Kodein.lazy {
import(androidXModule(this@ExampleApplication))
bind() from singleton { ExampleApiService }
bind() from singleton { AuthenticationApi() }
bind() from singleton { NetworkConnectivityInterceptor(instance()) }
bind() from singleton { ExampleDataBase(instance()) }
bind<UserRepository>() with singleton { UserRepository(instance(), instance()) }
bind() from provider { AuthenticationLoginViewModelFactory(instance(),instance()) }
bind() from provider { CreateAccountViewModelFactory(instance(),instance()) }
bind() from provider { PasswordViewModelFactory(instance(),instance()) }
}
override fun onCreate() {
super.onCreate()
DfreeApiService.init(this)
}
}
And in the object DfreeApiSercive:
object DfreeApiService {
private lateinit var application: Application
fun init(application: Application){
this.application=application
}
private lateinit var interceptor: HttpLoggingInterceptor
private lateinit var okHttpClient: OkHttpClient
private lateinit var networkConnectivityInterceptor: NetworkConnectivityInterceptor
val client: Retrofit
get() {
networkConnectivityInterceptor= NetworkConnectivityInterceptor(application.applicationContext)
interceptor = HttpLoggingInterceptor()
interceptor.level = HttpLoggingInterceptor.Level.BODY
okHttpClient= OkHttpClient.Builder()
.addInterceptor(networkConnectivityInterceptor)
.addInterceptor(interceptor)
...
}
}
And with this way you can import the context to an object.
Upvotes: 3