Java 致命例外:OkHttp 调度程序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/53613615/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 00:51:19  来源:igfitidea点击:

FATAL EXCEPTION: OkHttp Dispatcher

javaandroidokhttp

提问by fishhau

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.

我在我的 android 应用程序中使用 OkHttp 库向天气 API 发出 Web 请求。我已经实现了我的代码,并且在执行请求时遇到了 FATAL EXCEPTION。

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

我也已经在清单中添加了 INTERNET 权限。

MainActivity.java:

主活动.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.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.

我不知道此时该怎么办。我已经阅读并找到了一些关于这个主题的帖子。从我收集到的信息来看,必须在 runOnUiThread() 块中进行 UI 更改。但是我没有在我的代码中进行任何 UI 更改,我仍然遇到异常。

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

我也已经尝试将我的 JSON 解析代码放入 runOnUiThread() 并得到相同的 FATAL EXCEPTION 结果。有人有任何想法吗?

采纳答案by Stanislav Bondar

Responsebody can be consumed only once. You make it twice

Response身体只能消耗一次。你做了两次

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

More info in docs

文档中的更多信息

回答by Hillary Bett

Assign the response to a variable then you will be able to reuse it

将响应分配给变量,然后您就可以重用它

回答by Houssin Boulla

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

这是由于使用了不同版本的 OkHttp 造成的。确保 com.squareup.okhttp3 中的所有依赖项都使用相同的版本。

example:

例子:

implementation 'com.squareup.okhttp3:logging-interceptor:3.8.0'
implementation 'com.squareup.okhttp3:okhttp:3.8.0'

回答by Dejan Atanasov

I had the same issue and got it resolved by switching to Java 8 compatibility. Add compileOptionsunder your build.gradlefile.

我遇到了同样的问题,并通过切换到 Java 8 兼容性解决了这个问题。在build.gradle文件下添加compileOptions

android {

    ...
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}