致命异常:OkHttp Dispatcher

新手上路,请多包涵

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

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

主要活动.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);
    }

摇篮:

 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'
}

然后,这是我得到的异常:

 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)

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

我也已经尝试将我的 JSON 解析代码放在 runOnUiThread() 中并得到相同的致命异常结果。有人有什么想法吗?

原文由 fishhau 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.1k
2 个回答

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

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

文档 中的更多信息

原文由 Stanislav Bondar 发布,翻译遵循 CC BY-SA 4.0 许可协议

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

 android {

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

原文由 Dejan Atanasov 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏