如何在服务器处理完成后获取响应并校验结果?
解决:等异步网络请求完成后再校验结果
为啥会提前执行校验?
你这段代码里,httpPost方法是开新线程执行网络请求的,属于异步操作。按钮点击事件中,刚调用完httpPost,主线程就立刻去检查stringBuilder的内容——这时候网络请求还没跑完,服务器的响应还没存到stringBuilder里,自然校验不出正确结果。
解决方案:用回调接口实现异步通知
咱们可以定义一个回调接口,让网络请求完成后主动通知主线程,再在通知逻辑里做结果校验。
1. 在Server类中添加回调接口
用来传递请求的成功/失败状态,以及返回结果:
public interface OnHttpPostListener { void onSuccess(String response); void onFailure(Exception e); }
2. 修改Server类的httpPost方法
让方法接收回调参数,在请求完成后调用回调传递结果:
public class Server { String line; public void httpPost(String URL, OnHttpPostListener listener) { new Thread(new Runnable() { @Override public void run() { try { URL url = new URL(URL); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); connection.setDoOutput(true); connection.setDoInput(true); connection.setUseCaches(false); connection.connect(); int responseCode = connection.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { InputStream inputStream = connection.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); StringBuilder stringBuilder = new StringBuilder(); while ((line = reader.readLine()) != null) { stringBuilder.append(line); } // 请求成功,通过回调返回结果 if (listener != null) { listener.onSuccess(stringBuilder.toString()); } } else { // 响应码非200,视为请求失败 if (listener != null) { listener.onFailure(new Exception("响应码异常: " + responseCode)); } } } catch (Exception e) { e.printStackTrace(); // 请求出错,回调通知失败 if (listener != null) { listener.onFailure(e); } } } }).start(); } // 定义回调接口 public interface OnHttpPostListener { void onSuccess(String response); void onFailure(Exception e); } }
3. 修改按钮点击事件逻辑
调用httpPost时传入回调,在onSuccess方法里执行结果校验:
button.setOnClickListener(new View.OnClickListener() { @RequiresApi(api = Build.VERSION_CODES.O) @Override public void onClick(View view) { server.httpPost("https://google.com?username=Peter", new Server.OnHttpPostListener() { @Override public void onSuccess(String response) { // 这里是请求完成后才会执行的逻辑,可安全校验结果 if (response.contains("Successful")) { Log.d("test", response); } } @Override public void onFailure(Exception e) { // 处理请求失败的情况,比如打印错误日志 Log.e("test", "请求失败: " + e.getMessage()); } }); } });
额外说明
- 我把原来的成员变量
stringBuilder改成了方法内的局部变量——原写法如果同时发起多个请求,会存在线程安全问题,多个请求会争抢修改同一个stringBuilder导致数据混乱。 - 如果需要在回调里更新UI,记得用
runOnUiThread或者Handler切换回主线程,因为回调逻辑是在子线程中执行的,直接操作UI会引发崩溃。
内容的提问来源于stack exchange,提问作者Fgyfg Fyyf
相关产品推荐
相关产品推荐

