Android使用AsyncTask实现可以断点续传的DownloadManager功能

一个下载管理的DEMO,功能还不是很完善,使用的方式也不是很好,算是抛砖引玉吧。
只是简单的实现了多任务,支持断点续传的下载管理。

下面开始本次话题吧!

那么怎么用这玩意儿实现一个下载管理的功能?大体的思路是这样的:
  1.点击下载按钮以后,除了要让AsyncTask开始执行外,还要把下载的任务放到HashMap里面保存,这样做的好处就是能够在列表页进行管理,比如暂停、继续下载、取消。
  2.下载管理页的列表,使用ScrollView,而非ListView。这样做的好处就是为了能方便的更新ProgressBar进度。

  那咱先来说说启动下载任务。

btnDownload.setOnClickListener(newOnClickListener() {
    publicvoid onClick(View v) {
    String url = datas.get(position).get("url");
    Async asyncTask =null; // 下载renwu
    booleanisHas = false;
    // 判断当前要下载的这个连接是否已经正在进行,如果正在进行就阻止在此启动一个下载任务
    for(String urlString : AppConstants.listUrl) {
    if(url.equalsIgnoreCase(urlString)) {
    isHas =true;
    break;
    }
    }
    // 如果这个连接的下载任务还没有开始,就创建一个新的下载任务启动下载,并这个下载任务加到下载列表中
    if(isHas ==false) {
    asyncTask =new Async(); // 创建新异步
    asyncTask.setDataMap(datas.get(position));
    asyncTask.setContext(context);
    AppConstants.mapTask.put(url, asyncTask);
    // 当调用AsyncTask的方法execute时,就会去自动调用doInBackground方法
    asyncTask.executeOnExecutor(Executors.newCachedThreadPool(), url);
    }
}
    });



这里我为什么写asyncTask.executeOnExecutor(Executors.newCachedThreadPool(), url);而不是asyncTask.execute(url);呢?先卖个关子,回头咱再说。
   下面来看看Async里都干了啥。
这段代码就不贴出来了:在下面的demo里面有!

好了,下载任务已经启动了,接下来就该开始管理了。先说说之前错误的思路,估计大多数的网友可能跟我一样,一想到列表首先想到的就是ListView,这多简单啊,放一个ListView,继承BaseAdapter写个自己的Adapter,然后一展现,完事了,so easy。我也是这么想的,这省事啊,用了以后才发现,确实省事,不过更新ProgressBar的时候可是给我愁死了,无论怎么着都不能正常更新ProgressBar。在这个地方钻了一周的牛角尖,昨儿个突然灵光乍现,干嘛给自己挖个坑,谁说列表就非得用ListView了,我自己写个列表不就得了。

  先来看看列表页都有些什么

 packagecom.test.muldownloadtest;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ScrollView;
public class DownloadManagerActivity extendsActivity implementsOnClickListener {
privateScrollView scDownload;
privateLinearLayout llDownloadLayout;
@Override
protectedvoid onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.requestWindowFeature(Window.FEATURE_NO_TITLE)    ;
       this.setContentView(R.layout.download_manager_layout);
initView();}@Overrideprotectedvoid onResume() { super.onResume(); refreshItemView();}privatevoid initView(){ Button btnGoback = (Button)this.findViewById(R.id.btnGoback); btnGoback.setOnClickListener(this); scDownload = (ScrollView)this.findViewById(R.id.svDownload); scDownload.setSmoothScrollingEnabled(true); llDownloadLayout = (LinearLayout)this.findViewById(R.id.llDownloadLyout);}/*** 列表中的每一项*/privatevoid refreshItemView(){for (int i = 0; i < AppConstants.listUrl.size(); i++) { DownloadItemView downloadItemView =new DownloadItemView(this, AppConstants.listUrl.get(i), i); downloadItemView.setId(i); downloadItemView.setTag("downloadItemView_"+i); llDownloadLayout.addView(downloadItemView);}}public void onClick(View v) {switch (v.getId()) { case R.id.btnExit: this.finish(); break; case R.id.btnGoback: this.finish(); break; default: break; } }}


很简单,一个ScrollView,在这个ScrollView中在内嵌一个LinearLayout,用这个LinearLayout来存储每一个列表项。其实列表项很简单,最基本只要三个控件就行了——ProgressBar、TextView、Button。一个是进度条,一个显示百分比,一个用来暂停/继续,偷个懒,这个布局文件就不列出来了,咱就看看这个Button都干嘛了。
ublic void onClick(View v) {
switch (v。getId()) {
  case R。id。btnPauseOrResume:
     String btnTag = (String) btnPauseOrResume。getTag();
     if (btnTag。equals("pause")) {
     resumeDownload();
    }else if (btnTag。equals("resume")) {
      pauseDownload();
    }
    break;
default:
break;
}
}
privatevoid pauseDownload(){
btnPauseOrResume。setTag("pause");
btnPauseOrResume。setText(R。string。download_resume);
Async pauseTask =null;
// 判断当前被停止的这个任务在任务列表中是否存在,如果存在就暂停
if (AppConstants。linkedMapDownloading。containsKey(urlString)) {
pauseTask = AppConstants。linkedMapDownloading。get(urlString);
if (pauseTask != null) {
  pauseTask。pause();
}
}
}
privatevoid resumeDownload(){
btnPauseOrResume。setTag("resume");
btnPauseOrResume。setText(R。string。download_pause);
Async continueTask =null;
// 判断当前被停止的这个任务在任务列表中是否存在,如果存在就继续
if (AppConstants。linkedMapDownloading。containsKey(urlString)) {
continueTask = AppConstants。linkedMapDownloading。get(urlString);
if (continueTask != null) {
continueTask。continued();      }
}
handler。postDelayed(runnable,1000);
}



简单吧,就是判断一下当前按钮的Tag,然后根据Tag的值,来判断是继续下载,还是暂停下载。而这个暂停还是继续,其实只是修改下Async中的暂停标记的值,即paused是true还是false。

你可能感兴趣的:(Android使用AsyncTask实现可以断点续传的DownloadManager功能)