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

android使用AsyncTask实现多线程下载实例

程序员文章站 2023-12-19 13:53:40
asynctask不仅方便我们在子线程中对ui进行更新操作,还可以借助其本身的线程池来实现多线程任务。下面是一个使用asynctask来实现的多线程下载例子。 01 效果...

asynctask不仅方便我们在子线程中对ui进行更新操作,还可以借助其本身的线程池来实现多线程任务。下面是一个使用asynctask来实现的多线程下载例子。

01 效果图

android使用AsyncTask实现多线程下载实例

02 核心类 - downloadtask.class

public class downloadtask extends asynctask<string, integer, integer> {
  public static final int type_success = 0;
  public static final int type_failure = 1;
  public static final int type_pause = 2;
  public static final int type_cancel = 3;

  public int positiondownload;

  private boolean ispaused = false;
  private boolean iscancelled = false;

  private downloadlistener downloadlistener;
  private int lastprogress;

  public downloadtask(downloadlistener downloadlistener){
    this.downloadlistener = downloadlistener;
  }

  public void setdownloadlistener(downloadlistener downloadlistener){
    this.downloadlistener = downloadlistener;
  }

  @override
  protected integer doinbackground(string... params) {
    inputstream is = null;
    randomaccessfile savedfile = null;
    file file = null;

    long downloadlength = 0;
    string downloadurl = params[0];
    positiondownload = integer.parseint(params[1]);
    string filename = downloadurl.substring(downloadurl.lastindexof("/"));
    string directory = environment.getexternalstoragepublicdirectory(environment.directory_downloads).getpath();
    file = new file(directory + filename);

    if(file.exists()){
      downloadlength = file.length();
    }

    long contentlength = getcontentlength(downloadurl);
    if(contentlength == 0){
      return type_failure;
    } else if(contentlength == downloadlength){
      return type_success;
    }

    okhttpclient client = new okhttpclient();
    request request = new request.builder()
                  .addheader("range", "bytes="+downloadlength+"-")
                  .url(downloadurl)
                  .build();
    try {
      response response = client.newcall(request).execute();
      if(response != null){
        is = response.body().bytestream();
        savedfile = new randomaccessfile(file, "rw");
        savedfile.seek(downloadlength);
        byte[] buffer = new byte[1024];
        int total = 0;
        int length;

        while((length = is.read(buffer)) != -1){
          if(iscancelled){
            response.body().close();
            return type_cancel;
          } else if(ispaused) {
            response.body().close();
            return type_pause;
          }

          total += length;
          savedfile.write(buffer, 0, length);

          int progress = (int) ((total + downloadlength) * 100 / contentlength);
          int currentdownload = (int) (total + downloadlength);
          publishprogress(positiondownload, progress, currentdownload, (int) contentlength);
        }

        response.body().close();
        return type_success;
      }
    } catch (ioexception e) {
      e.printstacktrace();
    } finally {
      try {
        if(is != null) is.close();
        if(savedfile != null) savedfile.close();
        if(iscancelled && file != null) file.delete();
      } catch (ioexception e) {
        e.printstacktrace();
      }
    }

    return type_failure;
  }

  @override
  protected void onprogressupdate(integer... values) {
    int progress = values[1];
    if(progress > lastprogress){
      downloadlistener.onprogress(values[0], progress, values[2], values[3]);
      lastprogress = progress;
    }
  }

  @override
  protected void onpostexecute(integer status) {
    switch (status){
      case type_success:
        downloadlistener.onsuccess(positiondownload);
        break;
      case type_failure:
        downloadlistener.onfailure();
        break;
      case type_pause:
        downloadlistener.onpause();
        break;
      case type_cancel:
        downloadlistener.oncancel();
        break;
    }
  }

  public void pausedownload(){
    ispaused = true;
  }

  public void canceldownload(){
    iscancelled = true;
  }

  private long getcontentlength(string downloadurl) {
    okhttpclient client = new okhttpclient();
    request request = new request.builder()
                  .url(downloadurl)
                  .build();
    response response = null;
    try {
      response = client.newcall(request).execute();
      if(response != null && response.issuccessful()){
        long contentlength = response.body().contentlength();
        response.body().close();
        return contentlength;
      }
    } catch (ioexception e) {
      e.printstacktrace();
    }

    return 0;
  }
}

03 核心类 - downloadservice.class

public class downloadservice extends service {
  private map<string, downloadtask> downloadtaskmap = new hashmap<>();

  private downloadbinder mbinder = new downloadbinder();

  @override
  public ibinder onbind(intent intent) {
    return mbinder;
  }

  private notification getnotification(string title, int progress) {
    intent intent = new intent(this, mainactivity.class);
    pendingintent pendingintent = pendingintent.getactivity(this, 0, intent, 0);

    notificationcompat.builder builder = new notificationcompat.builder(this);
    builder.setsmallicon(r.mipmap.ic_launcher);
    builder.setlargeicon(bitmapfactory.decoderesource(getresources(), r.mipmap.ic_launcher));
    builder.setcontentintent(pendingintent);
    builder.setcontenttitle(title);
    if(progress > 0){
      builder.setcontenttext(progress + "%");
      builder.setprogress(100, progress, false);
    }


    return builder.build();
  }

  private notificationmanager getnotificationmanager() {
    return (notificationmanager) getsystemservice(notification_service);
  }


  class downloadbinder extends binder {
    public void startdownload(string url, int position, downloadlistener listener){
      if(!downloadtaskmap.containskey(url)){
        downloadtask downloadtask = new downloadtask(listener);
        downloadtask.executeonexecutor(asynctask.thread_pool_executor, url, position+"");
        downloadtaskmap.put(url, downloadtask);
        if(downloadtaskmap.size() == 1){
          startforeground(1, getnotification("正在下载" + downloadtaskmap.size(), -1));
        } else{
          getnotificationmanager().notify(1, getnotification("正在下载" + downloadtaskmap.size(), -1));
        }
      }
    }

    public void updatedownload(string url, downloadlistener listener){
      if(downloadtaskmap.containskey(url)){
        downloadtask downloadtask = downloadtaskmap.get(url);
        if(downloadtask != null){
          downloadtask.setdownloadlistener(listener);
        }
      }

    }

    public void pausedownload(string url){
      if(downloadtaskmap.containskey(url)){
        downloadtask downloadtask = downloadtaskmap.get(url);
        if(downloadtask != null){
          downloadtask.pausedownload();
        }

        downloadtaskmap.remove(url);

        if(downloadtaskmap.size() > 0){
          getnotificationmanager().notify(1, getnotification("正在下载" + downloadtaskmap.size(), -1));
        } else {
          stopforeground(true);
          getnotificationmanager().notify(1, getnotification("全部暂停下载", -1));
        }
      }
    }

    public void downloadsuccess(string url){
      if(downloadtaskmap.containskey(url)){
        downloadtask downloadtask = downloadtaskmap.get(url);
        downloadtaskmap.remove(url);
        if(downloadtask != null){
          downloadtask = null;
        }

        if(downloadtaskmap.size() > 0){
          getnotificationmanager().notify(1, getnotification("正在下载" + downloadtaskmap.size(), -1));
        } else {
          stopforeground(true);
          getnotificationmanager().notify(1, getnotification("下载成功", -1));
        }

      }
    }

    public boolean isdownloading(string url){
      if(downloadtaskmap.containskey(url)){
        return true;
      }

      return false;
    }

    public void canceldownload(string url){
      if(downloadtaskmap.containskey(url)){
        downloadtask downloadtask = downloadtaskmap.get(url);
        if(downloadtask != null){
          downloadtask.canceldownload();
        }
        downloadtaskmap.remove(url);

        if(downloadtaskmap.size() > 0){
          getnotificationmanager().notify(1, getnotification("正在下载" + downloadtaskmap.size(), -1));
        } else {
          stopforeground(true);
          getnotificationmanager().notify(1, getnotification("全部取消下载", -1));
        }
      }

      if(url != null){
        string filename = url.substring(url.lastindexof("/"));
        string directory = environment.getexternalstoragepublicdirectory(environment.directory_downloads).getpath();
        file file = new file(directory + filename);

        if(file.exists()){
          file.delete();
          toast.maketext(downloadservice.this, "deleted", toast.length_short).show();
        }
      }
    }
  }
}

04 源码

下载地址

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

上一篇:

下一篇: