web-dev-qa-db-fra.com

EXCEPTION FATALE: OkHttp Dispatcher

J'utilise la bibliothèque OkHttp dans mon Android pour faire des demandes Web à une API météo. J'ai déjà implémenté mon code et j'obtiens une EXCEPTION FATALE lorsque je fais la demande.

J'ai également ajouté des autorisations INTERNET dans mon manifeste.

MainActivity.Java:

private CurrentWeather currentWeather;

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        final ActivityMainBinding binding = DataBindingUtil.setContentView(MainActivity.this, R.layout.activity_main);

        String apiKey = "xxx";
        double latitude = 37.8267;
        double longitude = -122.4233;
        String forecastURL = String.format("https://api.darksky.net/forecast/%s/%f,%f", apiKey, latitude, longitude);

        if (isNetworkAvailable()) {
            OkHttpClient client = new OkHttpClient();

            Request request = new Request.Builder()
                    .url(forecastURL)
                    .build();

            Call call = client.newCall(request);
            call.enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {

                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    try {
                        Log.v(TAG, response.body().string());
                        String jsonData = response.body().string();
                        if (response.isSuccessful()) {
                            currentWeather = getCurrentDetails(jsonData);
                        }

                    } catch (IOException e) {
                        Log.e(TAG, e.getLocalizedMessage());
                    } catch (JSONException e) {
                        Log.e(TAG, e.getLocalizedMessage());
                    }
                }
            });
        }
        Log.d(TAG, "Main UI code is running");
    }

    private CurrentWeather getCurrentDetails(String jsonData) throws JSONException {

        JSONObject forecast = new JSONObject(jsonData);
        String timezone = forecast.getString("timezone");

        JSONObject currently = forecast.getJSONObject("currently");

        String icon = currently.getString("icon");
        String locationLabel = "Alcatraz Island";
        String summary = currently.getString("summary");
        long time = currently.getLong("time");
        double humidity = currently.getDouble("humidity");
        double precipProbability = currently.getDouble("precipProbability");
        double temperature = currently.getDouble("temperature");

        return new CurrentWeather(locationLabel, icon, time, temperature, humidity, precipProbability, summary, timezone);
    }

Gradle:

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.Android.support:appcompat-v7:28.0.0'
    implementation 'com.Android.support.constraint:constraint-layout:1.1.3'
    implementation 'com.squareup.okhttp3:okhttp:3.12.0'

    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.Android.support.test:runner:1.0.2'
    androidTestImplementation 'com.Android.support.test.espresso:espresso-core:3.0.2'
}

Ensuite, voici l'exception que je reçois:

2018-12-04 20:55:49.969 3314-3330/com.test.starmie E/AndroidRuntime: FATAL EXCEPTION: OkHttp Dispatcher
    Process: com.test.starmie, PID: 3314
    Java.lang.IllegalStateException: closed
        at okio.RealBufferedSource.rangeEquals(RealBufferedSource.Java:407)
        at okio.RealBufferedSource.rangeEquals(RealBufferedSource.Java:401)
        at okhttp3.internal.Util.bomAwareCharset(Util.Java:471)
        at okhttp3.ResponseBody.string(ResponseBody.Java:175)
        at com.test.starmie.MainActivity$1.onResponse(MainActivity.Java:66)
        at okhttp3.RealCall$AsyncCall.execute(RealCall.Java:206)
        at okhttp3.internal.NamedRunnable.run(NamedRunnable.Java:32)
        at Java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.Java:1133)
        at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:607)
        at Java.lang.Thread.run(Thread.Java:761)

Je ne sais pas quoi faire à ce stade. J'ai lu et trouvé quelques articles sur ce sujet. D'après ce que j'ai rassemblé, les changements d'interface utilisateur doivent être effectués dans le bloc runOnUiThread (). Mais je ne fais aucun changement d'interface ici dans mon code et je reçois toujours l'exception.

J'ai également déjà essayé de mettre mon code d'analyse JSON dans runOnUiThread () et j'ai obtenu le même résultat FATAL EXCEPTION. Quelqu'un a une idée?

4
fishhau

Response le corps ne peut être consommé qu'une seule fois. Tu le fais deux fois

Log.v(TAG, response.body().string());
String jsonData = response.body().string();

Plus d'informations dans docs

18
Stanislav Bondar

J'ai eu le même problème et je l'ai résolu en passant à Java 8. Ajoutez options de compilation sous votre build.gradle fichier.

Android {

    ...
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}
2
Dejan Atanasov

Assignez la réponse à une variable puis vous pourrez la réutiliser

1
Hillary Bett

Cela est dû à l'utilisation de différentes versions d'OkHttp. Assurez-vous que toutes vos dépendances de com.squareup.okhttp3 utilisent la même version.

exemple:

implementation 'com.squareup.okhttp3:logging-interceptor:3.8.0'
implementation 'com.squareup.okhttp3:okhttp:3.8.0'
1
Houssin Boulla