如何等待HttpURLConnection请求完成?Web连接器类返回null问题求助
解决异步网络请求导致返回值为null的问题
你的问题核心在于网络请求是异步执行的:GetWebApi方法启动了一个新线程去处理网络请求,但线程还没来得及完成请求、给sResult赋值,方法就已经返回了初始值null,所以tv.setText()拿到的是null。
要解决这个问题,我们不能让主线程等待网络请求(会导致ANR应用无响应),而是要通过回调机制在请求完成后再更新UI。下面是具体的修改方案:
1. 改造MyTest类,添加回调接口
首先定义一个回调接口,用来传递网络请求的成功/失败结果,同时完善资源管理和错误处理:
public class MyTest { private String sUrl = "http://Secret"; // 定义回调接口,用于传递请求结果 public interface WebApiCallback { void onSuccess(String result); void onError(Exception e); } // 修改方法:不再直接返回值,而是接收回调参数 public void getWebApi(final BaseRequest oRequest, final WebApiCallback callback) { new Thread(new Runnable() { @Override public void run() { HttpURLConnection con = null; BufferedReader br = null; try { URL url = new URL(sUrl); con = (HttpURLConnection) url.openConnection(); con.setRequestMethod(oRequest.GetHttpMethod()); // 先检查响应码,处理非成功的情况 int responseCode = con.getResponseCode(); if (responseCode != HttpURLConnection.HTTP_OK) { callback.onError(new Exception("请求失败,响应码:" + responseCode)); return; } br = new BufferedReader(new InputStreamReader(con.getInputStream())); StringBuilder sb = new StringBuilder(); String line; while ((line = br.readLine()) != null) { sb.append(line); } // 请求完成,通过回调返回结果 callback.onSuccess(sb.toString()); } catch (Exception ex) { callback.onError(ex); } finally { // 关闭资源,避免内存泄漏 if (br != null) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } if (con != null) { con.disconnect(); } } } }).start(); } }
2. 在Home Fragment中通过回调更新UI
因为Android要求UI操作必须在主线程执行,所以我们需要在回调方法里切换回主线程来更新TextView:
public class Home extends Fragment { public Home() { // Required empty public constructor } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_home, container, false); } @Override public void onStart() { super.onStart(); Button btn = getActivity().findViewById(R.id.button); final TextView tv = getActivity().findViewById(R.id.tv); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { LoginRequest oLoginRequest = new LoginRequest(); MyTest tt = new MyTest(); tt.getWebApi(oLoginRequest, new MyTest.WebApiCallback() { @Override public void onSuccess(final String result) { // 切换到主线程更新UI getActivity().runOnUiThread(new Runnable() { @Override public void run() { tv.setText(result); } }); } @Override public void onError(Exception e) { // 错误处理同样要在主线程执行 getActivity().runOnUiThread(new Runnable() { @Override public void run() { tv.setText("请求出错:" + e.getMessage()); } }); e.printStackTrace(); } }); } }); } }
方案优势说明
- 移除了原有的
sResult成员变量,避免了多线程下的线程安全问题 - 用回调机制保证只有在网络请求完成后才更新UI,确保拿到有效的响应结果
- 完善了资源关闭逻辑,避免内存泄漏
- 增加了响应码检查,能更合理地处理请求失败的场景
- 严格遵循Android线程规范,确保UI操作在主线程执行
内容的提问来源于stack exchange,提问作者Gs.
相关产品推荐
相关产品推荐

