多线程断点下载原理解析

原理:

1、将一个任务等分成几个小部分

2、开多个线程每个负责一个,记录每个线程其开始位置和结束位置

3、分别写入同一个文件,也是按起开始位置和结束位置写入。同时在下载时创建临时文件记录这次下载到哪儿

4、下载前看是否有上次记录,有则接着从后面下载

public class MainActivity extends AppCompatActivity {

	@BindView(R.id.btnDownload)
	Button mBtnDownload;
	@BindView(R.id.pbDownload)
	ProgressBar mPbDownload;
	@BindView(R.id.tvDownload)
	TextView mTvDownload;

	private static final int DOWNLOAD_SUCCESS = 0;
	private static final int DOWNLOAD_FAILURE = 1;
	private static final int DOWNLOADING = 2;
	private static final String DOWNLOAD_URL = "xxxxx";
	private static final String DOWNLOAD_PATH = Environment.getExternalStorageDirectory().getPath();
	@BindView(R.id.btnStop)
	Button mBtnStop;
	private int threadCount = 3;        //线程数量
	private PermissionListener mListener;
	private int downloadProgress = 0;
	private long finishedThread = 0;

	private volatile boolean mStopDownload = false;

	private Handler mHandler = new Handler(Looper.getMainLooper()) {

		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			switch (msg.what) {
				case DOWNLOAD_SUCCESS:
					mPbDownload.setProgress(mPbDownload.getMax());
					mTvDownload.setText("下载完成");
					break;
				case DOWNLOADING:
					Log.e("MainActivity", (long) mPbDownload.getProgress() * 100 / mPbDownload.getMax() + "%");
					mTvDownload.setText((long) mPbDownload.getProgress() * 100 / mPbDownload.getMax() + "%");
					break;
				case DOWNLOAD_FAILURE:
					mTvDownload.setText("下载失败");
					break;
				default:
					break;
			}
		}
	};


	@Override
	protected void onCreate(@Nullable Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		ButterKnife.bind(this);

		mBtnDownload.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				mStopDownload = false;
				requestPermission(new String[]{}, new PermissionListener() {
					@Override
					public void onGranted() {
						new Thread(new Runnable() {
							@Override
							public void run() {
								try {
									URL url = new URL(DOWNLOAD_URL);
									HttpURLConnection connection = (HttpURLConnection) url.openConnection();
									connection.setRequestMethod("GET");     //设置请求模式
									connection.setConnectTimeout(5000);     //设置连接超时
									connection.setReadTimeout(5000);        //设置读取超时

									//完整下载 code:200  部分下载 code:206
									if (connection.getResponseCode() == 200) {
										int length = connection.getContentLength();        //获得下载文件大小
										//创建临时文件
										File file = new File(DOWNLOAD_PATH, getName(DOWNLOAD_URL));
										RandomAccessFile raf = new RandomAccessFile(file, "rwd");

										//临时文件占位,防止下载到一半空间不足
										raf.setLength(length);
										raf.close();

										//设置最大进度条
										mPbDownload.setMax(length);
										//计算每个线程下载区间
										int size = length / threadCount;

										for (int i = 0; i < threadCount; i++) {
											int startIndex = i * size;     //开始下载位置
											int endIndex = (i + 1) * size - 1;     //结束下载位置
											if (i == threadCount - 1) {
												endIndex = length - 1;
											}
											Log.e("MainActivity", "线程:" + i + ",下载区间:" + startIndex + "~" + endIndex);
											new MyDownload(i, startIndex, endIndex).start();
										}
									}
								} catch (Exception e) {
									e.printStackTrace();
									mHandler.sendEmptyMessage(DOWNLOAD_FAILURE);
								}
							}
						}).start();
					}

					@Override
					public void onDenied(List<String> deniedPermission) {
						Toast.makeText(MainActivity.this, "need Permission", Toast.LENGTH_SHORT).show();
					}
				});
			}
		});

		mBtnStop.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				mStopDownload = true;
			}
		});
	}


	public static String getName(String path) {
		int index = path.lastIndexOf("/");
		return path.substring(index + 1);
	}

	/**
	 * 权限请求
	 *
	 * @param permissions
	 * @param listener
	 */
	public void requestPermission(String[] permissions, PermissionListener listener) {
		mListener = listener;
		List<String> permissionList = new ArrayList<>();        //权限集合
		for (String permission : permissions) {
			if (ActivityCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
				permissionList.add(permission);
			}
		}
		if (permissionList.isEmpty()) {
			listener.onGranted();
		} else {
			ActivityCompat.requestPermissions(this, permissionList.toArray(new String[permissionList.size()]), 1);
		}
	}

	@Override
	public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
		super.onRequestPermissionsResult(requestCode, permissions, grantResults);
		switch (requestCode) {
			case 1:
				if (grantResults.length > 0) {
					List<String> deniedPermission = new ArrayList<>();
					for (int i = 0; i < grantResults.length; i++) {
						int grantResult = grantResults[i];      //授权结果
						String permission = permissions[i];     //授权名称
						if (grantResult != PackageManager.PERMISSION_GRANTED) {
							deniedPermission.add(permission);
						}
						if (deniedPermission.isEmpty()) {
							mListener.onGranted();
						} else {
							mListener.onDenied(deniedPermission);
						}
					}
				}
				break;
			default:
				break;
		}
	}

	/**
	 * 下载线程
	 */
	class MyDownload extends Thread {

		private int threadId;
		private int startIndex;
		private int endIndex;

		public MyDownload(int threadId, int startIndex, int endIndex) {
			super();
			this.threadId = threadId;
			this.startIndex = startIndex;
			this.endIndex = endIndex;
		}

		@Override
		public void run() {
			super.run();
			try {
				File fileProgress = new File(Environment.getExternalStorageDirectory(), threadId + ".txt");
				int lastProgress = 0;
				if (fileProgress.exists()) {
					//读取进度临时文件中的内容
					FileInputStream fis = new FileInputStream(fileProgress);
					BufferedReader br = new BufferedReader(new InputStreamReader(fis));
					//得到上一次下载进度
					lastProgress = Integer.parseInt(br.readLine());
					//改变下载的开始位置,上一次下过的,这次就不请求了
					startIndex += lastProgress;
					fis.close();

					//把上一次下载进度加到进度条进度中
					downloadProgress += lastProgress;
					//发送消息,让文本进度条改变
					mHandler.sendEmptyMessage(DOWNLOADING);
				}
				URL url = new URL(DOWNLOAD_URL);
				HttpURLConnection connection = (HttpURLConnection) url.openConnection();
				connection.setRequestMethod("GET");     //设置请求模式
				connection.setConnectTimeout(5000);     //设置连接超时
				connection.setReadTimeout(5000);        //设置读取超时

				//设置请求数据的区间  Range:区间
				connection.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex);
				//完整下载 code:200  部分下载 code:206
				if (connection.getResponseCode() == 206) {
					InputStream is = connection.getInputStream();

					byte[] buffer = new byte[1024];
					int len = 0;
					//当前线程下载的总进度
					int total = lastProgress;
					File file = new File(DOWNLOAD_PATH, MainActivity.getName(DOWNLOAD_URL));
					RandomAccessFile raf = new RandomAccessFile(file, "rwd");
					//设置写入的开始位置
					raf.seek(startIndex);
					while ((len = is.read(buffer)) != -1) {
						if (mStopDownload) {
							break;
						}
						raf.write(buffer, 0, len);
						total += len;
//                      Log.e("MyDownload", "线程:" + threadId + ",下载了:" + total);

						//创建临时文件保存下载进度
						RandomAccessFile rafProgress = new RandomAccessFile(fileProgress, "rwd");
						rafProgress.write((total + "").getBytes());
						rafProgress.close();

						//每次下载len个长度的字节,马上把len加到下载进度中,让进度条能反应这len个长度的下载进度
						downloadProgress += len;
						mPbDownload.setProgress(downloadProgress);
						mHandler.sendEmptyMessage(DOWNLOADING);
					}
					raf.close();

					//3条线程全部下载完毕,才去删除进度临时文件
					finishedThread++;

					synchronized (DOWNLOAD_URL) {
						if (finishedThread == threadCount) {
							//断点下载可能会造成数据记录不准确,依靠线程结束来刷新界面
							mHandler.sendEmptyMessage(DOWNLOAD_SUCCESS);
							for (int i = 0; i < threadCount; i++) {
								File f = new File(Environment.getExternalStorageDirectory(), i + ".txt");
								f.delete();
							}
							finishedThread = 0;
						}
					}
//					//判断是否用户手动暂停
//					if (!mStopDownload) {
//						//3条线程全部下载完毕,才去删除进度临时文件
//						finishedThread++;
//
//						synchronized (DOWNLOAD_URL) {
//							if (finishedThread == threadCount) {
//								//断点下载可能会造成数据记录不准确,依靠线程结束来刷新界面
//								mHandler.sendEmptyMessage(DOWNLOAD_SUCCESS);
//								for (int i = 0; i < threadCount; i++) {
//									File f = new File(Environment.getExternalStorageDirectory(), i + ".txt");
//									f.delete();
//								}
//								finishedThread = 0;
//							}
//						}
//					}
				}
			} catch (Exception e) {
				e.printStackTrace();
				mHandler.sendEmptyMessage(DOWNLOAD_FAILURE);
			}
		}
	}

}

另外推荐使用三方多线程下载框架:xUtils3

https://github.com/wyouflf/xUtils

导入以下代码

package com.leixiansheng.test.download;

import com.lidroid.xutils.db.annotation.Transient;
import com.lidroid.xutils.http.HttpHandler;

import java.io.File;

/**
 * Author: wyouflf
 * Date: 13-11-10
 * Time: 下午8:11
 */
public class DownloadInfo {

    public DownloadInfo() {
    }

    private long id;

    @Transient
    private HttpHandler<File> handler;

    private HttpHandler.State state;

    private String downloadUrl;

    private String fileName;

    private String fileSavePath;

    private long progress;

    private long fileLength;

    private boolean autoResume;

    private boolean autoRename;


    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public HttpHandler<File> getHandler() {
        return handler;
    }

    public void setHandler(HttpHandler<File> handler) {
        this.handler = handler;
    }

    public HttpHandler.State getState() {
        return state;
    }

    public void setState(HttpHandler.State state) {
        this.state = state;
    }

    public String getDownloadUrl() {
        return downloadUrl;
    }

    public void setDownloadUrl(String downloadUrl) {
        this.downloadUrl = downloadUrl;
    }

    public String getFileName() {
        return fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    public String getFileSavePath() {
        return fileSavePath;
    }

    public void setFileSavePath(String fileSavePath) {
        this.fileSavePath = fileSavePath;
    }

    public long getProgress() {
        return progress;
    }

    public void setProgress(long progress) {
        this.progress = progress;
    }

    public long getFileLength() {
        return fileLength;
    }

    public void setFileLength(long fileLength) {
        this.fileLength = fileLength;
    }

    public boolean isAutoResume() {
        return autoResume;
    }

    public void setAutoResume(boolean autoResume) {
        this.autoResume = autoResume;
    }

    public boolean isAutoRename() {
        return autoRename;
    }

    public void setAutoRename(boolean autoRename) {
        this.autoRename = autoRename;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof DownloadInfo)) return false;

        DownloadInfo that = (DownloadInfo) o;

        if (id != that.id) return false;

        return true;
    }

    @Override
    public int hashCode() {
        return (int) (id ^ (id >>> 32));
    }
}
package com.leixiansheng.test.download;

import android.content.Context;
import android.database.Cursor;
import com.lidroid.xutils.DbUtils;
import com.lidroid.xutils.HttpUtils;
import com.lidroid.xutils.db.converter.ColumnConverter;
import com.lidroid.xutils.db.converter.ColumnConverterFactory;
import com.lidroid.xutils.db.sqlite.ColumnDbType;
import com.lidroid.xutils.db.sqlite.Selector;
import com.lidroid.xutils.exception.DbException;
import com.lidroid.xutils.exception.HttpException;
import com.lidroid.xutils.http.HttpHandler;
import com.lidroid.xutils.http.ResponseInfo;
import com.lidroid.xutils.http.callback.RequestCallBack;
import com.lidroid.xutils.util.LogUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * Author: wyouflf
 * Date: 13-11-10
 * Time: 下午8:10
 */
public class DownloadManager {

    private List<DownloadInfo> downloadInfoList;

    private int maxDownloadThread = 3;

    private Context mContext;
    private DbUtils db;

    /*package*/ DownloadManager(Context appContext) {
        ColumnConverterFactory.registerColumnConverter(HttpHandler.State.class, new HttpHandlerStateConverter());
        mContext = appContext;
        db = DbUtils.create(mContext);
        try {
            downloadInfoList = db.findAll(Selector.from(DownloadInfo.class));
        } catch (DbException e) {
            LogUtils.e(e.getMessage(), e);
        }
        if (downloadInfoList == null) {
            downloadInfoList = new ArrayList<DownloadInfo>();
        }
    }

    public int getDownloadInfoListCount() {
        return downloadInfoList.size();
    }

    public DownloadInfo getDownloadInfo(int index) {
        return downloadInfoList.get(index);
    }

    public void addNewDownload(String url, String fileName, String target,
                               boolean autoResume, boolean autoRename,
                               final RequestCallBack<File> callback) throws DbException {
        final DownloadInfo downloadInfo = new DownloadInfo();
        downloadInfo.setDownloadUrl(url);
        downloadInfo.setAutoRename(autoRename);
        downloadInfo.setAutoResume(autoResume);
        downloadInfo.setFileName(fileName);
        downloadInfo.setFileSavePath(target);
        HttpUtils http = new HttpUtils();
        http.configRequestThreadPoolSize(maxDownloadThread);
        HttpHandler<File> handler = http.download(url, target, autoResume, autoRename, new ManagerCallBack(downloadInfo, callback));
        downloadInfo.setHandler(handler);
        downloadInfo.setState(handler.getState());
        downloadInfoList.add(downloadInfo);
        db.saveBindingId(downloadInfo);
    }

    public void resumeDownload(int index, final RequestCallBack<File> callback) throws DbException {
        final DownloadInfo downloadInfo = downloadInfoList.get(index);
        resumeDownload(downloadInfo, callback);
    }

    public void resumeDownload(DownloadInfo downloadInfo, final RequestCallBack<File> callback) throws DbException {
        HttpUtils http = new HttpUtils();
        http.configRequestThreadPoolSize(maxDownloadThread);
        HttpHandler<File> handler = http.download(
                downloadInfo.getDownloadUrl(),
                downloadInfo.getFileSavePath(),
                downloadInfo.isAutoResume(),
                downloadInfo.isAutoRename(),
                new ManagerCallBack(downloadInfo, callback));
        downloadInfo.setHandler(handler);
        downloadInfo.setState(handler.getState());
        db.saveOrUpdate(downloadInfo);
    }

    public void removeDownload(int index) throws DbException {
        DownloadInfo downloadInfo = downloadInfoList.get(index);
        removeDownload(downloadInfo);
    }

    public void removeDownload(DownloadInfo downloadInfo) throws DbException {
        HttpHandler<File> handler = downloadInfo.getHandler();
        if (handler != null && !handler.isCancelled()) {
            handler.cancel();
        }
        downloadInfoList.remove(downloadInfo);
        db.delete(downloadInfo);
    }

    public void stopDownload(int index) throws DbException {
        DownloadInfo downloadInfo = downloadInfoList.get(index);
        stopDownload(downloadInfo);
    }

    public void stopDownload(DownloadInfo downloadInfo) throws DbException {
        HttpHandler<File> handler = downloadInfo.getHandler();
        if (handler != null && !handler.isCancelled()) {
            handler.cancel();
        } else {
            downloadInfo.setState(HttpHandler.State.CANCELLED);
        }
        db.saveOrUpdate(downloadInfo);
    }

    public void stopAllDownload() throws DbException {
        for (DownloadInfo downloadInfo : downloadInfoList) {
            HttpHandler<File> handler = downloadInfo.getHandler();
            if (handler != null && !handler.isCancelled()) {
                handler.cancel();
            } else {
                downloadInfo.setState(HttpHandler.State.CANCELLED);
            }
        }
        db.saveOrUpdateAll(downloadInfoList);
    }

    public void backupDownloadInfoList() throws DbException {
        for (DownloadInfo downloadInfo : downloadInfoList) {
            HttpHandler<File> handler = downloadInfo.getHandler();
            if (handler != null) {
                downloadInfo.setState(handler.getState());
            }
        }
        db.saveOrUpdateAll(downloadInfoList);
    }

    public int getMaxDownloadThread() {
        return maxDownloadThread;
    }

    public void setMaxDownloadThread(int maxDownloadThread) {
        this.maxDownloadThread = maxDownloadThread;
    }

    public class ManagerCallBack extends RequestCallBack<File> {
        private DownloadInfo downloadInfo;
        private RequestCallBack<File> baseCallBack;

        public RequestCallBack<File> getBaseCallBack() {
            return baseCallBack;
        }

        public void setBaseCallBack(RequestCallBack<File> baseCallBack) {
            this.baseCallBack = baseCallBack;
        }

        private ManagerCallBack(DownloadInfo downloadInfo, RequestCallBack<File> baseCallBack) {
            this.baseCallBack = baseCallBack;
            this.downloadInfo = downloadInfo;
        }

        @Override
        public Object getUserTag() {
            if (baseCallBack == null) return null;
            return baseCallBack.getUserTag();
        }

        @Override
        public void setUserTag(Object userTag) {
            if (baseCallBack == null) return;
            baseCallBack.setUserTag(userTag);
        }

        @Override
        public void onStart() {
            HttpHandler<File> handler = downloadInfo.getHandler();
            if (handler != null) {
                downloadInfo.setState(handler.getState());
            }
            try {
                db.saveOrUpdate(downloadInfo);
            } catch (DbException e) {
                LogUtils.e(e.getMessage(), e);
            }
            if (baseCallBack != null) {
                baseCallBack.onStart();
            }
        }

        @Override
        public void onCancelled() {
            HttpHandler<File> handler = downloadInfo.getHandler();
            if (handler != null) {
                downloadInfo.setState(handler.getState());
            }
            try {
                db.saveOrUpdate(downloadInfo);
            } catch (DbException e) {
                LogUtils.e(e.getMessage(), e);
            }
            if (baseCallBack != null) {
                baseCallBack.onCancelled();
            }
        }

        @Override
        public void onLoading(long total, long current, boolean isUploading) {
            HttpHandler<File> handler = downloadInfo.getHandler();
            if (handler != null) {
                downloadInfo.setState(handler.getState());
            }
            downloadInfo.setFileLength(total);
            downloadInfo.setProgress(current);
            try {
                db.saveOrUpdate(downloadInfo);
            } catch (DbException e) {
                LogUtils.e(e.getMessage(), e);
            }
            if (baseCallBack != null) {
                baseCallBack.onLoading(total, current, isUploading);
            }
        }

        @Override
        public void onSuccess(ResponseInfo<File> responseInfo) {
            HttpHandler<File> handler = downloadInfo.getHandler();
            if (handler != null) {
                downloadInfo.setState(handler.getState());
            }
            try {
                db.saveOrUpdate(downloadInfo);
            } catch (DbException e) {
                LogUtils.e(e.getMessage(), e);
            }
            if (baseCallBack != null) {
                baseCallBack.onSuccess(responseInfo);
            }
        }

        @Override
        public void onFailure(HttpException error, String msg) {
            HttpHandler<File> handler = downloadInfo.getHandler();
            if (handler != null) {
                downloadInfo.setState(handler.getState());
            }
            try {
                db.saveOrUpdate(downloadInfo);
            } catch (DbException e) {
                LogUtils.e(e.getMessage(), e);
            }
            if (baseCallBack != null) {
                baseCallBack.onFailure(error, msg);
            }
        }
    }

    private class HttpHandlerStateConverter implements ColumnConverter<HttpHandler.State> {

        @Override
        public HttpHandler.State getFieldValue(Cursor cursor, int index) {
            return HttpHandler.State.valueOf(cursor.getInt(index));
        }

        @Override
        public HttpHandler.State getFieldValue(String fieldStringValue) {
            if (fieldStringValue == null) return null;
            return HttpHandler.State.valueOf(fieldStringValue);
        }

        @Override
        public Object fieldValue2ColumnValue(HttpHandler.State fieldValue) {
            return fieldValue.value();
        }

        @Override
        public ColumnDbType getColumnDbType() {
            return ColumnDbType.INTEGER;
        }
    }
}
package com.leixiansheng.test.download;

import android.app.ActivityManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import com.lidroid.xutils.exception.DbException;
import com.lidroid.xutils.util.LogUtils;

import java.util.List;

/**
 * Author: wyouflf
 * Date: 13-11-10
 * Time: 上午1:04
 */
public class DownloadService extends Service {

    private static DownloadManager DOWNLOAD_MANAGER;

    public static DownloadManager getDownloadManager(Context appContext) {
        if (!DownloadService.isServiceRunning(appContext)) {
            Intent downloadSvr = new Intent(appContext, DownloadService.class);
            appContext.startService(downloadSvr);
        }
        if (DownloadService.DOWNLOAD_MANAGER == null) {
            DownloadService.DOWNLOAD_MANAGER = new DownloadManager(appContext);
        }
        return DOWNLOAD_MANAGER;
    }

    public DownloadService() {
        super();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
    }

    @Override
    public void onDestroy() {
        if (DOWNLOAD_MANAGER != null) {
            try {
                DOWNLOAD_MANAGER.stopAllDownload();
                DOWNLOAD_MANAGER.backupDownloadInfoList();
            } catch (DbException e) {
                LogUtils.e(e.getMessage(), e);
            }
        }
        super.onDestroy();
    }

    public static boolean isServiceRunning(Context context) {
        boolean isRunning = false;

        ActivityManager activityManager =
                (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningServiceInfo> serviceList
                = activityManager.getRunningServices(Integer.MAX_VALUE);

        if (serviceList == null || serviceList.size() == 0) {
            return false;
        }

        for (int i = 0; i < serviceList.size(); i++) {
            if (serviceList.get(i).service.getClassName().equals(DownloadService.class.getName())) {
                isRunning = true;
                break;
            }
        }
        return isRunning;
    }
}

在需要的地方按照以下代码调用即可:

private static final String DOWNLOAD_URL = "http://mys-src.oss-cn-shanghai.aliyuncs.com/source/mys.apk";
 
	private DownloadManager downloadManager;

	@Override
	protected void onCreate(@Nullable Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		ButterKnife.bind(this);
		downloadManager = DownloadService.getDownloadManager(getApplicationContext());

		mBtnDownload.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				String target = "/sdcard/test/" + "test.apk";
				try {
					downloadManager.addNewDownload(DOWNLOAD_URL,
							"mys",		//
							target,				//保存路径
							true, // 如果目标文件存在,接着未完成的部分继续下载。服务器不支持RANGE时将从新下载。
							false, // 如果从请求返回信息中获取到文件名,下载完成后自动重命名。
							new RequestCallBack<File>() {
								@Override
								public void onSuccess(ResponseInfo<File> responseInfo) {
									mTvDownload.setText("下载完成");
									Log.e("SecondActivity", responseInfo.result.getPath());
								}

								@Override
								public void onFailure(HttpException e, String s) {
									mTvDownload.setText("下载失败:" + s);
								}

								@Override
								public void onLoading(long total, long current, boolean isUploading) {
									super.onLoading(total, current, isUploading);
									mTvDownload.setText((current * 100) / total + "%");
								}

								@Override
								public void onStart() {
									mTvDownload.setText("等待下载···");
								}
							});
				} catch (DbException e) {
					LogUtils.e(e.getMessage(), e);
				}
			}
		});

		mBtnStop.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				try {
					int index = downloadManager.getDownloadInfoListCount();
					downloadManager.stopDownload(index-1);
				} catch (DbException e) {
					e.printStackTrace();
				}
			}
		});
	}

猜你喜欢

转载自blog.csdn.net/Mr_Leixiansheng/article/details/85288831
今日推荐