Android中使用AsyncTask实现下载文件动态更新进度条功能
1. 泛型
aysnctask<params, progress, result>
params:启动任务时传入的参数,通过调用asynctask.execute(param)方法传入。
progress:后台任务执行的进度,若不用显示进度条,则不需要指定。
result:后台任务结束时返回的结果。
2. 重要方法
doinbackground(params... params):必须重写的方法,后台任务就在这里执行,会开启一个新的线程。params为启动任务时传入的参数,参数个数不定。
onpreexecute():在主线程中调用,在后台任务开启前的操作在这里进行,例如显示一个进度条对话框。
onpostexecute(result result):当后台任务结束后,在主线程中调用,处理doinbackground()方法返回的结果。
onprogressupdate(progress... values):当在doinbackground()中调用publishprogress(progress... values)时,返回主线程中调用,这里的参数个数也是不定的。
oncancelled():取消任务。
3. 注意事项
(1)execute()方法必须在主线程中调用;
(2)asynctask实例必须在主线程中创建;
(3)不要手动调用doinbackground()、onpreexecute()、onpostexecute()、onprogressupdate()方法;
(4)注意防止内存泄漏,在doinbackground()方法中若出现对activity的强引用,可能会造成内存泄漏。
4. 下载文件动态更新进度条(未封装)
布局:
<?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="20dp" tools:context="com.studying.asynctaskdemo.mainactivity"> <progressbar android:id="@+id/progressbar" style="?android:progressbarstylehorizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:progress="0" /> <button android:id="@+id/download" android:layout_width="match_parent" android:layout_height="50dp" android:layout_margintop="20dp" android:text="@string/start_btn" /> <textview android:id="@+id/status" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margintop="20dp" android:text="@string/waiting" /> </linearlayout>
activity:
public class mainactivity extends activity { private static final string file_name = "test.pdf";//下载文件的名称 private static final string pdf_url = "http://clfile.imooc.com/class/assist/118/1328281/asynctask.pdf"; private progressbar mprogressbar; private button mdownloadbtn; private textview mstatus; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); initview(); setlistener(); } private void initview() { mprogressbar = (progressbar) findviewbyid(r.id.progressbar); mdownloadbtn = (button) findviewbyid(r.id.download); mstatus = (textview) findviewbyid(r.id.status); } private void setlistener() { mdownloadbtn.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { //asynctask实例必须在主线程创建 downloadasynctask asynctask = new downloadasynctask(); asynctask.execute(pdf_url); } }); } /** * 泛型: * string:传入参数为文件下载地址 * integer:下载过程中更新progressbar的进度 * boolean:是否下载成功 */ private class downloadasynctask extends asynctask<string, integer, boolean> { private string mfilepath;//下载文件的保存路径 @override protected boolean doinbackground(string... params) { if (params != null && params.length > 0) { string pdfurl = params[0]; try { url url = new url(pdfurl); urlconnection urlconnection = url.openconnection(); inputstream in = urlconnection.getinputstream(); int contentlength = urlconnection.getcontentlength();//获取内容总长度 mfilepath = environment.getexternalstoragedirectory() + file.separator + file_name; //若存在同名文件则删除 file pdffile = new file(mfilepath); if (pdffile.exists()) { boolean result = pdffile.delete(); if (!result) { return false; } } int downloadsize = 0;//已经下载的大小 byte[] bytes = new byte[1024]; int length = 0; outputstream out = new fileoutputstream(mfilepath); while ((length = in.read(bytes)) != -1) { out.write(bytes, 0, length); downloadsize += length; publishprogress(downloadsize / contentlength * 100); } in.close(); out.close(); } catch (ioexception e) { e.printstacktrace(); return false; } } else { return false; } return true; } @override protected void onpreexecute() { super.onpreexecute(); mdownloadbtn.settext("下载中"); mdownloadbtn.setenabled(false); mstatus.settext("下载中"); mprogressbar.setprogress(0); } @override protected void onpostexecute(boolean aboolean) { super.onpostexecute(aboolean); mdownloadbtn.settext("下载完成"); mstatus.settext(aboolean ? "下载完成" + mfilepath : "下载失败"); } @override protected void onprogressupdate(integer... values) { super.onprogressupdate(values); if (values != null && values.length > 0) { mprogressbar.setprogress(values[0]); } } } }
5. 下载文件动态更新进度条(封装)
activity:
public class mainactivity extends activity { private static final string file_name = "test.pdf"; private static final string pdf_url = "http://clfile.imooc.com/class/assist/118/1328281/asynctask.pdf"; private progressbar mprogressbar; private button mdownloadbtn; private textview mstatus; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); initview(); setlistener(); } private void initview() { mprogressbar = (progressbar) findviewbyid(r.id.progressbar); mdownloadbtn = (button) findviewbyid(r.id.download); mstatus = (textview) findviewbyid(r.id.status); } private void setlistener() { mdownloadbtn.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { string localpath = environment.getexternalstoragedirectory() + file.separator + file_name; downloadhelper.download(pdf_url, localpath, new downloadhelper.ondownloadlistener() { @override public void onstart() { mdownloadbtn.settext("下载中"); mdownloadbtn.setenabled(false); mstatus.settext("下载中"); mprogressbar.setprogress(0); } @override public void onsuccess(file file) { mdownloadbtn.settext("下载完成"); mstatus.settext(string.format("下载完成:%s", file.getpath())); } @override public void onfail(file file, string failinfo) { mdownloadbtn.settext("开始下载"); mdownloadbtn.setenabled(true); mstatus.settext(string.format("下载失败:%s", failinfo)); } @override public void onprogress(int progress) { mprogressbar.setprogress(progress); } }); } }); } }
downloadhelper:
class downloadhelper { static void download(string url, string localpath, ondownloadlistener listener) { downloadasynctask task = new downloadasynctask(url, localpath, listener); task.execute(); } private static class downloadasynctask extends asynctask<string, integer, boolean> { private string mfailinfo; private string murl; private string mfilepath; private ondownloadlistener mlistener; downloadasynctask(string murl, string mfilepath, ondownloadlistener mlistener) { this.murl = murl; this.mfilepath = mfilepath; this.mlistener = mlistener; } @override protected boolean doinbackground(string... params) { string pdfurl = murl; try { url url = new url(pdfurl); urlconnection urlconnection = url.openconnection(); inputstream in = urlconnection.getinputstream(); int contentlength = urlconnection.getcontentlength(); file pdffile = new file(mfilepath); if (pdffile.exists()) { boolean result = pdffile.delete(); if (!result) { mfailinfo = "存储路径下的同名文件删除失败!"; return false; } } int downloadsize = 0; byte[] bytes = new byte[1024]; int length; outputstream out = new fileoutputstream(mfilepath); while ((length = in.read(bytes)) != -1) { out.write(bytes, 0, length); downloadsize += length; publishprogress(downloadsize / contentlength * 100); } in.close(); out.close(); } catch (ioexception e) { e.printstacktrace(); mfailinfo = e.getmessage(); return false; } return true; } @override protected void onpreexecute() { super.onpreexecute(); if (mlistener != null) { mlistener.onstart(); } } @override protected void onpostexecute(boolean aboolean) { super.onpostexecute(aboolean); if (mlistener != null) { if (aboolean) { mlistener.onsuccess(new file(mfilepath)); } else { mlistener.onfail(new file(mfilepath), mfailinfo); } } } @override protected void onprogressupdate(integer... values) { super.onprogressupdate(values); if (values != null && values.length > 0) { if (mlistener != null) { mlistener.onprogress(values[0]); } } } } interface ondownloadlistener{ void onstart(); void onsuccess(file file); void onfail(file file, string failinfo); void onprogress(int progress); } }
总结
以上所述是小编给大家介绍的android中使用asynctask实现下载文件动态更新进度条功能,希望对大家有所帮助