欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android中使用AsyncTask实现下载文件动态更新进度条功能

程序员文章站 2023-12-10 20:03:10
1. 泛型 aysnctask params:启动任务时传入的参数,通过调用asynctask.exec...

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():取消任务。

Android中使用AsyncTask实现下载文件动态更新进度条功能

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实现下载文件动态更新进度条功能,希望对大家有所帮助