连接丢失后如何传递到Dagger参数操作的模块:(()-> Unit)进行重复请求

时间:2018-10-15 13:26:47

标签: android kotlin dagger

我想检查Internet连接,并使用ConnectivityInterceptor并将参数action: (() -> Unit)传递到dagger(NetworkModule)的模块,以在连接丢失后进行重复调用请求,该怎么办?

@Module
class NetworkModule {

    private fun getOkHttpClient(context: Context, action: (() -> Unit)): OkHttpClient {
        return OkHttpClient.Builder()
                .hostnameVerifier { s, sslSession -> true }
                .connectTimeout(TIME.toLong(), TimeUnit.SECONDS)
                .readTimeout(TIME.toLong(), TimeUnit.SECONDS)
                .writeTimeout(TIME.toLong(), TimeUnit.SECONDS)
                .addInterceptor(HttpLoggingInterceptor().setLevel(if (BuildConfig.DEBUG) HttpLoggingInterceptor.Level.BODY else HttpLoggingInterceptor.Level.NONE))
                .addInterceptor(ConnectivityInterceptor(context, action))
                .addInterceptor { chain ->
                    val original = chain.request()
                    val requestBuilder = original.newBuilder()

                    val token = BEARER + UserStorage.getInstance().token
                    val uuid = UserStorage.getInstance().uuid

                    val userAgent = Build.MANUFACTURER + " / " + Build.MODEL + " / " + Build.VERSION.RELEASE + " / " + VERSION_NAME + " / Android"

                    if (!TextUtils.isEmpty(UserStorage.getInstance().token)) {
                        requestBuilder.header(AUTHORIZATION, token)
                    }
                    if (!TextUtils.isEmpty(UserStorage.getInstance().uuid)) {
                        requestBuilder.header(X_UUID, UserStorage.getInstance().uuid)
                    }
                    requestBuilder.header(USER_AGENT, userAgent)
                    requestBuilder
                            .header("Accept", "application/json")
                            .method(original.method(), original.body())
                    chain.proceed(requestBuilder.build())
                }
                .retryOnConnectionFailure(true)
                .build()
    }

    @Provides
    @Singleton
    fun provideRetrofit(gson: Gson, context: Context, action: (() -> Unit)): Retrofit {
        return Retrofit.Builder()
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(ScalarsConverterFactory.create()) // this line cut quotes
                .addConverterFactory(GsonConverterFactory.create(gson))
                .client(getOkHttpClient(context, action))
                .baseUrl(BASE_URL)
                .build()
    } ...

我的ConnectivityInterceptor:

class ConnectivityInterceptor(private val context: Context, private val action: (() -> Unit)): Interceptor {

    @Throws(IOException::class)
    override fun intercept(chain: Interceptor.Chain): Response {
        if (!isNetworkAvailable(context)) {
            showErrorScreen(context, action, ERROR_CLIENT)
        }
        val builder = chain.request().newBuilder()
        return chain.proceed(builder.build())
    }

}

我的AppModule:

@Module
class AppModule(private val app: App) {

    @Provides
    @Singleton
    fun provideContext(): Context = app

    @Provides
    fun provideApplication(): Application = app

    @Provides
    @Singleton
    fun providesGson(): Gson =
            GsonBuilder()
                    .serializeNulls()
                    .setLenient()
                    .registerTypeAdapterFactory(ArrayAdapterFactory())
                    .setDateFormat("yyyy-MM-dd HH:mm:ss")
                    .create()

}

我的服务:

interface ApiService {

    @GET(VERSION)
    fun getVersion(): Observable<VersionResponse>

    @GET(DICTIONARIES)
    fun getDictionaries(): Observable<JsonObject>
...

class NetworkManager @Inject constructor(private val api: ApiVideo) {

    fun getVersion(): Observable<VersionResponse> {
        return api.getVersion()
    }

    fun getDictionaries(): Observable<JsonObject> {
        return api.getDictionaries()
    } ...

例如-我的主持人:

class SplashPresenter @Inject constructor(): SplashContract.Presenter {

    @Inject
    lateinit var apiManager: NetworkManager
    private var compositeDisposable = CompositeDisposable()
    var view: SplashContract.View? = null

    override fun detachView(view: SplashContract.View) {
        this.view = null
    }

    override fun attachView(view: SplashContract.View) {
        this.view = view
    }

    override fun destroy() {
        compositeDisposable.clear()
    }

    override fun getDictionaries(context: Context) {
        view?.let {
            apiManager.getDictionaries()
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribeOn(Schedulers.io())
                    .subscribe({ result ->
                        LocalizationData.getInstance(context).saveData(result)
                        view?.showOrHideProgressBar(false)
                        view?.goNextScreen()
                    }, { error ->
                        handleAnyError(view!!, error, context) { getDictionaries(context) }
                    }).addToCompositeDisposable(compositeDisposable)
        }
    }

    override fun getVersion(context: Context) {
        view?.let {
                apiManager.getVersion()
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribeOn(Schedulers.io())
                        .subscribe({ result ->
                            view?.showOrHideProgressBar(false)
                            view?.showResultVersion(result)
                        }, { error ->
                            handleAnyError(view!!, error, context) { getVersion(context) }
                        }).addToCompositeDisposable(compositeDisposable)
        }
    }

}

1 个答案:

答案 0 :(得分:1)

我认为Dagger不支持匿名lambda。

通过引用Kotlin lambda创建普通的命名类

class LostConnectivityAction : () -> Unit {
    override fun invoke() {
        // do something
    }
}

您可以像其他任何课程一样在Dagger Module中@Provide进行该课程。