'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?
Solution 1:[1]
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
Solution 2:[2]
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
}
}
Solution 3:[3]
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'
Solution 4:[4]
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`
to
import java.io.IOException
data class ApiException(val errorMessage: String?) : IOException(errorMessage)
Really don't know why java.lang.Exception
caused such issue.
Solution 5:[5]
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
Solution 6:[6]
Assign the response to a variable then you will be able to reuse it
Solution 7:[7]
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"
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Stanislav Bondar |
Solution 2 | Dejan Atanasov |
Solution 3 | Houssin Boulla |
Solution 4 | li2 |
Solution 5 | hammadsyr |
Solution 6 | Hillary Bett |
Solution 7 | Leonardo Alves Machado |