Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

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?

I'm actually following an android online course and the instructor uses OkHttp in this project. – fishhau Dec 4, 2018 at 13:05

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'

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

I tried all answers, even migrate okhttp from 3.14.9 to 4.4.0, but none worked for my case: I had a response interceptor inherited from Interceptor,

class ResponseInterceptor : Interceptor {
    @Throws(IOException::class)
    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request()
        val response = chain.proceed(request)
        if (!isSuccessful(response.code)) {
            handleErrorResponse(response)
        return response
    private fun handleErrorResponse(response: Response) {
        throw ApiException(response.body?.string()) // only called one time!

I finally fixed it by change

data class ApiException(val errorMessage: String?) : Exception(errorMessage)
// `Exception` is `typealias Exception = java.lang.Exception`
import java.io.IOException
data class ApiException(val errorMessage: String?) : IOException(errorMessage)

Really don't know why java.lang.Exception caused such issue.

in my case, i already called response.body.string() once but still got the crash. got it fixed with

ResponseBody responseBodyCopy = response.peekBody(Long.MAX_VALUE);
responseBodyCopy.string();

from this comment on github : https://github.com/square/okhttp/issues/1240#issuecomment-330813274

dependencies {
 implementation "com.squareup.okhttp3:okhttp:4.2.1"
 compile "com.squareup.okhttp3:logging-interceptor:4.2.1"
 compile "com.squareup.okhttp3:okhttp-urlconnection:4.2.1"
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.