首页 > 解决方案 > Android 在对象中传递上下文

问题描述

我需要将应用程序上下文传递给一个对象。这是在我的连接服务okhttpClient中调用一个函数进行拦截。我正在使用对象类通过改造和与我的服务的外部接口来建立与服务器的连接。

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

   }

}

下面的代码是我的界面:

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)
        }
    }
  }

我正在使用 mvvm 和 kodein。如果没有互联网拦截器,应用程序会在没有互联网时崩溃。 我的拦截器:

    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
    }
}

感谢您的关注

标签: androidkotlinmvvmandroid-contextkodein

解决方案


在主活动中:

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)
}

}

在对象 DfreeApiServive 中:

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)
...
}
}

通过这种方式,您可以将上下文导入对象。


推荐阅读