You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中JSON POST请求ProgressBar不显示问题求助

嘿,我帮你定位到问题啦!你的ProgressBar不显示,核心原因是网络请求直接阻塞了UI主线程,导致UI没法及时更新。

问题根源

Android里UI更新(比如设置ProgressBar可见)必须在主线程执行,但耗时的网络请求如果也放在主线程,会把主线程“卡”住——你点击按钮后虽然设置了progressBar.setVisibility(View.VISIBLE),但紧接着就执行了同步的网络请求,主线程被这个请求占满,根本没时间去刷新UI展示ProgressBar。等请求完成后,你又马上把ProgressBar设为GONE,所以它完全没机会显示出来。

解决方案:用异步任务把网络请求移到子线程

我们需要把耗时的网络请求放到子线程,让主线程专心处理UI更新。这里用Android提供的AsyncTask来实现,它能帮我们轻松管理后台任务和UI线程的交互。

修改后的完整代码示例:

@Override protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_leave);
    progressBar = findViewById(R.id.progressBarLeave);
    submit_button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            // 点击后立刻显示ProgressBar
            progressBar.setVisibility(View.VISIBLE);
            // 启动异步任务执行网络请求
            new SubmitDataTask().execute();
        }
    });
}

// 自定义AsyncTask,负责后台请求和主线程结果处理
private class SubmitDataTask extends AsyncTask<Void, Void, JSONObject> {

    @Override
    protected JSONObject doInBackground(Void... voids) {
        // 这个方法在子线程运行,专门处理耗时操作
        try {
            String api_url = "https://url/";
            String json_request = "{\"test\":"+1+"}";
            Log.e("driver_loc", json_request); // 修正了你原来写错的变量名
            return call_api(api_url, json_request);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    protected void onPostExecute(JSONObject response_data) {
        // 这个方法在主线程运行,处理请求结果和UI更新
        progressBar.setVisibility(View.GONE);
        if (response_data != null) {
            try {
                Log.e("response", String.valueOf(response_data));
                if(response_data.getString("status").equals("1")) {
                    Toast.makeText(Leave.this, "Success", Toast.LENGTH_LONG).show();
                } else {
                    Toast.makeText(Leave.this, "Request failed", Toast.LENGTH_LONG).show();
                }
            } catch (JSONException e) {
                e.printStackTrace();
                Toast.makeText(Leave.this, "Failed to parse response", Toast.LENGTH_LONG).show();
            }
        } else {
            Toast.makeText(Leave.this, "Network request failed", Toast.LENGTH_LONG).show();
        }
    }
}

// 保留网络请求方法,但优化异常处理和响应校验
public JSONObject call_api(String api_url, String request_data) {
    try {
        URL url = new URL(api_url);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("POST");
        conn.setDoInput(true);
        conn.setDoOutput(true);
        // 添加请求头,告诉服务器我们发送的是JSON格式
        conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
        
        OutputStream os = conn.getOutputStream();
        BufferedWriter writer = new BufferedWriter(
            new OutputStreamWriter(os, "UTF-8"));
        writer.write(request_data);
        writer.flush();
        writer.close();
        os.close();
        
        // 检查响应码,确保请求成功
        int responseCode = conn.getResponseCode();
        if (responseCode != HttpURLConnection.HTTP_OK) {
            Log.e("API Error", "Response Code: " + responseCode);
            return null;
        }
        
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        StringBuilder response = new StringBuilder();
        String line;
        while ((line = bufferedReader.readLine()) != null) {
            response.append(line);
        }
        bufferedReader.close();
        Log.d("API Response", response.toString());
        return new JSONObject(response.toString());
    } catch (Exception e) {
        Log.e("API Exception", e.toString());
        // 子线程不能弹Toast,只打日志,后续在主线程处理异常提示
        return null;
    }
}
几个重要提醒
  1. 绝对不要在主线程跑网络请求:Android早就禁止这种操作了,轻则UI卡顿,重则触发ANR(应用无响应)崩溃。
  2. UI操作必须在主线程:像设置ProgressBar、弹Toast这些操作,一定要放在主线程执行,AsyncTask的onPostExecute就是专门干这个的。
  3. 异常处理要规范:原来的call_api里不要弹Toast,因为子线程不能直接操作UI,把异常信息带回主线程再处理。
  4. 变量名修正:你原来代码里Log.e("driver_loc", location_request);的location_request是笔误,应该是json_request,我已经帮你修正了。

内容的提问来源于stack exchange,提问作者Geek Boy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:40:49