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

如何使用AsyncTask在PDF加载前实现实时水平内容加载进度条

实现带实时进度的PDF加载进度条方案

第一步:添加水平进度条布局

在你的页面XML布局中添加对应进度条控件:

<ProgressBar
    android:id="@+id/contentLoadingProgressBar"
    style="@style/Widget.AppCompat.ProgressBar.Horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:max="100"
    android:progress="0"
    android:visibility="VISIBLE" />

第二步:修改AsyncTask实现进度监听

你需要将原AsyncTask的泛型参数调整为<String, Integer, InputStream>,第二个Integer参数用于传递进度值,完整修改后代码如下:

class RetrievePDFStream extends AsyncTask<String, Integer, InputStream> {
    private ProgressBar progressBar;

    // 构造方法传入进度条实例,若为Activity内部类可直接访问成员变量省略该步骤
    public RetrievePDFStream(ProgressBar progressBar) {
        this.progressBar = progressBar;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        // 加载前重置进度,显示进度条
        progressBar.setProgress(0);
        progressBar.setVisibility(View.VISIBLE);
    }

    @Override
    protected InputStream doInBackground(String... strings) {
        InputStream inputStream = null;
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            URL urlx = new URL(strings[0]);
            HttpURLConnection urlConnection = (HttpURLConnection) urlx.openConnection();
            if (urlConnection.getResponseCode() == 200) {
                inputStream = new BufferedInputStream(urlConnection.getInputStream());
                // 获取PDF文件总大小
                int totalLength = urlConnection.getContentLength();
                byte[] buffer = new byte[1024];
                int readBytes;
                int currentBytes = 0;
                // 边读取边计算实时进度
                while ((readBytes = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, readBytes);
                    currentBytes += readBytes;
                    // 仅在能拿到总大小的情况计算进度
                    if (totalLength > 0) {
                        int progress = (int) ((currentBytes * 100) / totalLength);
                        publishProgress(progress);
                    }
                }
                return new ByteArrayInputStream(outputStream.toByteArray());
            }
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        } finally {
            // 资源回收
            try {
                if (inputStream != null) inputStream.close();
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        // 更新进度条显示
        progressBar.setProgress(values[0]);
    }

    @Override
    protected void onPostExecute(InputStream inputStream) {
        // 加载完成隐藏进度条
        progressBar.setVisibility(View.GONE);
        if (inputStream != null) {
            pdfView.fromStream(inputStream).load();
        } else {
            Toast.makeText(progressBar.getContext(), "PDF加载失败,请检查网络或文件地址", Toast.LENGTH_SHORT).show();
        }
    }
}

第三步:调用执行

在需要触发PDF加载的位置传入进度条实例执行任务即可:

ProgressBar loadingBar = findViewById(R.id.contentLoadingProgressBar);
new RetrievePDFStream(loadingBar).execute("你要加载的PDF文件URL地址");

补充说明

  • 如果服务端没有返回Content-Length响应头,会拿不到文件总大小,此时可以将进度条设置为不确定模式progressBar.setIndeterminate(true)即可
  • AsyncTask从Android 11(API 30)开始被标记为废弃,如果你面向新版本开发,可以替换为Kotlin协程、AsyncTaskLoader或者WorkManager实现相同效果

内容的提问来源于stack exchange,提问作者Anil Kumhar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.16 18:36:04