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的进度更新机制,步骤如下:
- 修改mp4load方法:获取文件总大小,累计已下载字节数,计算进度并调用
publishProgress()发送进度; - 重写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
相关产品推荐
相关产品推荐

