Android Build a Weather App Hooking Up the Model to the View Plugging in the Data

Jovy Ong
Jovy Ong
Front End Web Development Techdegree Student 13,947 Points

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)

1 Answer

In your try block, you're calling response.body().string() twice, but the body can only be consumed once. Just pass jsonData in your Log.v instead and it should be ok:

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