Дооснащение: java .lang.IllegalStateException: закрыто - PullRequest
1 голос
/ 13 марта 2020

Я использую два вида перехватчиков, один - HttpLoggingInterceptor , а другой - мой пользовательский AuthorizationInterceptor

Я использую ниже обновленную библиотеку модифицированных версий,

def retrofit_version = "2.7.2"
implementation "com.squareup.retrofit2:retrofit:$retrofit_version"
implementation "com.squareup.retrofit2:converter-gson:$retrofit_version"
implementation 'com.squareup.okhttp3:logging-interceptor:4.4.0'
implementation 'com.squareup.okhttp3:okhttp:4.4.0'

ниже приведен код

private fun makeOkHttpClient(): OkHttpClient {
        val logger = HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)
        return OkHttpClient.Builder()
            .addInterceptor(AuthorizationInterceptor(context)) <---- To put Authorization Barrier
            .addInterceptor(logger) <---- To log Http request and response
            .followRedirects(false)
            .connectTimeout(50, TimeUnit.SECONDS)
            .readTimeout(50, TimeUnit.SECONDS)
            .writeTimeout(50, TimeUnit.SECONDS)
            .build()
    }

Когда я пытаюсь выполнить приведенный ниже код в файле с именем SynchronizationManager.kt, он выдает ошибку.

var rulesResourcesServices = RetrofitInstance(context).buildService(RulesResourcesServices::class.java)
val response = rulesResourcesServices.getConfigFile(file).execute() <---In this line I am getting an exception... (which is at SynchronizationManager.kt:185)               

My Класс RulesResourcesServices находится здесь

После отладки я обнаружил, что при вызове функции ниже, в это время я получаю исключение

@GET("users/me/configfile")
    fun getConfigFile(@Query("type") type: String): Call<ResponseBody>

Я получаю следующую ошибку

java.lang.IllegalStateException: closed
at okio.RealBufferedSource.read(RealBufferedSource.kt:184)
at okio.ForwardingSource.read(ForwardingSource.kt:29)
at retrofit2.OkHttpCall$ExceptionCatchingResponseBody$1.read(OkHttpCall.java:288)
at okio.RealBufferedSource.readAll(RealBufferedSource.kt:293)
at retrofit2.Utils.buffer(Utils.java:316)<------- ANDROID IS HIGH-LIGHTING
at retrofit2.BuiltInConverters$BufferingResponseBodyConverter.convert(BuiltInConverters.java:103)
at retrofit2.BuiltInConverters$BufferingResponseBodyConverter.convert(BuiltInConverters.java:96)
at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:225)
at retrofit2.OkHttpCall.execute(OkHttpCall.java:188)
at retrofit2.DefaultCallAdapterFactory$ExecutorCallbackCall.execute(DefaultCallAdapterFactory.java:97)
at android.onetap.SynchronizationManager.downloadFile(SynchronizationManager.kt:185)
at android.base.repository.LoginRepository.downloadConfigFilesAndLocalLogin(LoginRepository.kt:349)
at android.base.repository.LoginRepository.access$downloadConfigFilesAndLocalLogin(LoginRepository.kt:48)
at android.base.repository.LoginRepository$loginTask$2.onSRPLoginComplete(LoginRepository.kt:210)
at android.base.repository.LoginRepository$performSyncLogin$srpLogin$1$1.onSRPLogin(LoginRepository.kt:478)
at android.srp.SRPManager$SRPLoginOperation$execute$1.invokeSuspend(SRPManager.kt:323)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:561)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:727)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:667)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:655)

Ниже приведен скриншот, на котором вы видите, что я получаю вывод файла, но не знаю, почему он вызывает исключение.

enter image description here

проверен Класс утилит Retrofit

https://github.com/square/retrofit/blob/master/retrofit/src/main/java/retrofit2/Utils.java

static ResponseBody buffer(final ResponseBody body) throws IOException {
    Buffer buffer = new Buffer();
    body.source().readAll(buffer); <-This line throws an error.
    return ResponseBody.create(body.contentType(), body.contentLength(), buffer);
  }

Обновление

То же самое работает нормально с методом enqueue.

response.enqueue(object : Callback<ResponseBody?> {

override fun onResponse(call: Call<ResponseBody?>, response: retrofit2.Response<ResponseBody?>) { 
 }
})

У меня есть такая же проблема с командой Retrofit, давайте посмотрим.

https://github.com/square/retrofit/issues/3336

1 Ответ

0 голосов
/ 19 марта 2020

Благодаря JakeWharton (https://github.com/square/retrofit/issues/3336) я могу получить решение. На самом деле в моем пользовательском перехватчике я читал ответ, используя следующий код

Response.body().string()

, который я делал, потому что приведенный выше код помог мне выяснить, есть ли какая-либо ошибка, чем какая это ошибка ....

если это AUTH_ERROR, я должен сгенерировать новый токен и добавить его к заголовку запроса.

В соответствии с документом дооснащения , если мы вызываем любой из методов ниже, тогда ответ будет закрыт, что означает, что он не доступен для использования обычными внутренними компонентами Retrofit.

Response.close()
Response.body().close()
Response.body().source().close()
Response.body().charStream().close()
Response.body().byteStream().close()
Response.body().bytes()
Response.body().string()

Таким образом, для чтения данных вместо response.body (). string () Я буду использовать response.peekBody (2048) .string () , поэтому он не закроет ответ.

ниже - код

 val response = chain.proceed(request)
            val body = response.peekBody(2048).string()
            try {
                if (response.isSuccessful) {
                    if (body.contains("status")) {
                        val jsonObject = JSONObject(body)
                        val status = jsonObject.optInt("status")
                        Timber.d("Status = $status")
                        if (status != null && status == 0) {
                            val errorCode = jsonObject.getJSONObject("data").optString("error_code")
                            if (errorCode != null) {
                                addRefreshTokenToRequest(request)
                                return chain.proceed(request)
                            }
                        }
                    } else {
                        Timber.d("Body is not containing status, might be not valid GSON")
                    }
                }
                Timber.d("End")

            } catch (e: Exception) {
                e.printStackTrace()
                Timber.d("Error")
            }
            return response
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...