OkHttp3(Android Java)请求响应异常及首次请求失效问题求助
问题排查与解决方案
一、首次语音识别后API请求未触发
- 检查语音识别回调逻辑,确保
onResults中直接触发POST请求,而非依赖二次状态触发
确认在onResults回调里,获取到语音结果后立即调用请求方法,避免将结果存储到全局变量后等待其他事件触发:@Override public void onResults(Bundle results) { ArrayList<String> matches = results.getStringArrayList(RecognizerIntent.EXTRA_RESULTS); if (matches != null && !matches.isEmpty()) { String voiceContent = matches.get(0); // 直接调用POST请求方法 sendVoiceResultToApi(voiceContent); } } - 排查是否过滤了首次识别结果:比如误判首次结果为空,或错误依赖
onPartialResults回调(该回调仅返回部分识别内容,首次完整结果需在onResults中处理)
二、响应仅显示单个“{”
这是响应体读取不完整导致的,通常是错误读取了单个字符或未完整读取响应流:
- 错误示例(仅读取第一个字符):
// 错误写法 char singleChar = response.body().charStream().read(); errorView.setText(String.valueOf(singleChar)); - 正确读取完整响应体:使用
response.body().string()一次性读取全部内容(注意该方法只能调用一次,流读取后会关闭):if (response.isSuccessful()) { try { String fullResponse = response.body().string(); errorView.setText(fullResponse); } catch (IOException e) { errorView.setText("读取响应失败:" + e.getMessage()); } } else { errorView.setText("请求失败,状态码:" + response.code()); }
三、同步execute()抛异常无有效信息
Android禁止在主线程执行网络请求,同步execute()直接在主线程调用会抛出NetworkOnMainThreadException,且若未正确捕获并输出异常信息,就无法定位问题:
- 必须将同步请求放在子线程执行,且更新UI需切回主线程:
new Thread(() -> { OkHttpClient client = new OkHttpClient(); // 构建请求体 RequestBody requestBody = RequestBody.create( MediaType.parse("application/json; charset=utf-8"), "{\"content\":\"" + voiceContent + "\"}" ); Request request = new Request.Builder() .url("你的目标API地址") .post(requestBody) .build(); try { Response response = client.newCall(request).execute(); // 切回主线程更新UI runOnUiThread(() -> { if (response.isSuccessful()) { try { errorView.setText(response.body().string()); } catch (IOException e) { errorView.setText("响应读取失败:" + e.getMessage()); } } else { errorView.setText("请求失败:" + response.code()); } }); } catch (IOException e) { e.printStackTrace(); // 打印完整异常栈到Logcat runOnUiThread(() -> errorView.setText("请求异常:" + e.getMessage())); } }).start(); - 额外检查:确保已添加网络权限到
AndroidManifest.xml
若目标API为HTTP协议(非HTTPS),Android 9及以上需在<uses-permission android:name="android.permission.INTERNET" />AndroidManifest.xml的application标签中添加android:usesCleartextTraffic="true",或配置网络安全策略。
内容的提问来源于stack exchange,提问作者Rikudou
相关产品推荐
相关产品推荐

