Issue
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?
Solution
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
Answered By - Stanislav Bondar
Answer Checked By - Marie Seifert (JavaFixing Admin)