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

Android:视频下载进度条实现及AsyncTask代码正确性验证

关于Android视频下载进度条的实现与代码检查

嘿,我来帮你搞定这个下载进度条的问题~先看你写的那段进度条代码,再一步步完善下载逻辑。

一、你写的AsyncTask进度条代码是否正确?

你的代码核心逻辑是对的,但有几个关键小问题需要补全,否则没法正常工作:

  • 缺少bar.show():你在onPreExecute里初始化了ProgressDialog,但没调用show()方法,对话框根本不会弹出来;
  • 参数类型不匹配:你的AsyncTask泛型是AsyncTask<String, Integer, String>,所以onPostExecute的参数应该是String,而不是Void,否则会编译报错;
  • 上下文有效性:要确保传入的activity是当前活跃的Activity,避免使用已销毁的上下文引发内存泄漏;
  • API兼容提示:如果你的项目目标API是26及以上,ProgressDialog已经被标记为废弃,推荐用DialogFragment或者Material Design的ProgressIndicator替代,旧项目继续用也可以,但需要注意兼容性。

补全后的基础版本代码大概是这样:

// 先在类里声明ProgressDialog变量
private ProgressDialog bar;
private Activity activity;

// 记得在构造方法里传入Activity上下文
public DownloadFile1(Activity activity) {
    this.activity = activity;
}

@Override
protected void onPreExecute() {
    super.onPreExecute();
    bar = new ProgressDialog(activity);
    bar.setMessage("正在下载...");
    bar.setIndeterminate(true); // 圆形不确定进度条
    bar.show(); // 关键:显示对话框
}

@Override
protected void onPostExecute(String result) {
    super.onPostExecute(result);
    if (bar != null && bar.isShowing()) {
        bar.dismiss(); // 确保对话框存在且显示时才关闭
    }
}

二、如何结合下载逻辑实现进度条?

分两种场景给你实现方案:

1. 圆形不确定进度条(简单版)

如果只需要显示“正在下载”的圆形动画,不需要具体百分比,那把上面补全的onPreExecute和onPostExecute加到你的DownloadFile1类里,再修正泛型参数匹配问题,就可以正常工作了。下载期间对话框会一直显示,下载完成后自动关闭。

2. 带百分比的确定进度条(进阶版)

如果想让用户看到具体下载进度,需要利用AsyncTask的进度更新机制,步骤如下:

  1. 修改mp4load方法:获取文件总大小,累计已下载字节数,计算进度并调用publishProgress()发送进度;
  2. 重写onProgressUpdate方法:更新进度条的显示进度。

完整修改后的代码示例:

class DownloadFile1 extends AsyncTask<String, Integer, String> {
    public String videoToDownload;
    public String fileName;
    private ProgressDialog bar;
    private Activity activity;

    // 传入Activity上下文
    public DownloadFile1(Activity activity) {
        this.activity = activity;
    }

    @Override
    protected String doInBackground(String... params) {
        try {
            mp4load(videoToDownload);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "下载完成";
    }

    public void mp4load(String urling) {
        try {
            System.out.println("Downloading");
            URL url = new URL(urling);
            HttpURLConnection con = (HttpURLConnection) url.openConnection();
            con.setRequestMethod("GET");
            con.connect();

            // 获取文件总大小
            long totalSize = con.getContentLength();
            long downloadedSize = 0;

            File SDCardRoot = Environment.getExternalStorageDirectory();
            File outputFile = new File(SDCardRoot, fileName);
            if (!outputFile.exists()) {
                outputFile.createNewFile();
            }

            FileOutputStream fos = new FileOutputStream(outputFile);
            InputStream is = con.getInputStream();
            byte[] buffer = new byte[1024];
            int len1 = 0;
            while ((len1 = is.read(buffer)) != -1) {
                fos.write(buffer, 0, len1);
                downloadedSize += len1;
                // 计算进度百分比,发送给主线程更新UI
                int progress = (int) ((downloadedSize * 100) / totalSize);
                publishProgress(progress);
            }
            fos.close();
            is.close();
            System.out.println("Downloaded");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        bar = new ProgressDialog(activity);
        bar.setMessage("正在下载...");
        bar.setIndeterminate(false); // 关闭不确定模式
        bar.setMax(100); // 设置进度最大值
        bar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); // 水平进度条
        bar.show();
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        if (bar != null) {
            bar.setProgress(values[0]); // 更新进度条
        }
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        if (bar != null && bar.isShowing()) {
            bar.dismiss();
        }
        // 这里可以加下载完成的提示,比如Toast
        Toast.makeText(activity, result, Toast.LENGTH_SHORT).show();
    }
}

注意事项

  • 权限:别忘了在AndroidManifest.xml里添加网络权限和存储权限:
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <!-- Android 10及以上需要申请MANAGE_EXTERNAL_STORAGE或者使用MediaStore -->
    
  • 内存泄漏:如果Activity在下载过程中销毁,要及时取消AsyncTask并关闭对话框,避免内存泄漏。

内容的提问来源于stack exchange,提问作者Nikeshh Vijayabaskaran

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 09:05:38