Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FATAL EXCEPTION: OkHttp Dispatcher

I'm using the OkHttp library in my android app to make web requests to a weather API. I've already implemented my code and I'm getting a FATAL EXCEPTION when doing the request.

I've already added INTERNET permissions in my manifest too.

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

Then, here's the exception I'm getting:

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)

I don't know what to do at this point. I've read around and found a few posts regarding this topic. From what I've gathered, UI changes must be made in the runOnUiThread() block. But I'm not making any UI changes here in my code and I still get the exception.

I've also already tried putting my JSON parsing code in the runOnUiThread() and got the same FATAL EXCEPTION result. Anyone got any ideas?

like image 519
fishhau Avatar asked Dec 04 '18 13:12

fishhau


3 Answers

Response body can be consumed only once. You make it twice

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

More info in docs

like image 191
Stanislav Bondar Avatar answered Nov 17 '22 22:11

Stanislav Bondar


This is caused by using different versions of OkHttp. Ensure all your dependencies from com.squareup.okhttp3 are using the same version.

example:

implementation 'com.squareup.okhttp3:logging-interceptor:3.8.0'
implementation 'com.squareup.okhttp3:okhttp:3.8.0'
like image 43
Houssin Boulla Avatar answered Nov 17 '22 21:11

Houssin Boulla


I had the same issue and got it resolved by switching to Java 8 compatibility. Add compileOptions under your build.gradle file.

android {

    ...
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}
like image 10
Dejan Atanasov Avatar answered Nov 17 '22 23:11

Dejan Atanasov