FileDownlaoder
- 支持多任務(wù)下載
- 支持多線程下載
- 支持 斷點(diǎn)續(xù)傳
github地址:
https://github.com/lingochamp/FileDownloader
FileDownloader的基本使用
- manifest.xml中聲明權(quán)限
<uses-permission android:name="android.permission.INTERNET" />
<!-- When you invoke BaseDownloadTask#setWifiRequired(true), you need declare ACCESS_NETWORK_STATE permission -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
- build.gradle 引入
dependencies {
implementation 'com.liulishuo.filedownloader:library:1.7.3'
}
- Application中初始化 FileDownloader
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
Log.d("feifei","MyApplication.onCreate()");
FileDownloader.setupOnApplicationOnCreate(this)
.connectionCreator(new FileDownloadUrlConnection
.Creator(new FileDownloadUrlConnection.Configuration()
.connectTimeout(15_000) // set connection timeout.
.readTimeout(15_000) // set read timeout.
))
.commit();
}
}
單任務(wù)下載
BaseDownloadTask singleTask ;
public int singleTaskId = 0;
String apkUrl = "http://cdn.llsapp.com/android/LLS-v4.0-595-20160908-143200.apk";
String singleFileSaveName = "liulishuo.apk";
public String mSinglePath = FileDownloadUtils.getDefaultSaveRootPath()+ File.separator+"feifei_save"
+File.separator+singleFileSaveName;;
public String mSaveFolder = FileDownloadUtils.getDefaultSaveRootPath()+File.separator+"feifei_save";
public void start_single(){
String url = apkUrl;
singleTask = FileDownloader.getImpl().create(url)
// .setPath(mSinglePath,false)
.setPath(mSinglePath,true)
.setCallbackProgressTimes(300)
.setMinIntervalUpdateSpeed(400)
//.setTag()
.setListener(new FileDownloadSampleListener(){
@Override
protected void pending(BaseDownloadTask task, int soFarBytes, int totalBytes) {
Log.d("feifei","pending taskId:"+task.getId()+",soFarBytes:"+soFarBytes+",totalBytes:"+totalBytes+",percent:"+soFarBytes*1.0/totalBytes);
}
@Override
protected void progress(BaseDownloadTask task, int soFarBytes, int totalBytes) {
Log.d("feifei","progress taskId:"+task.getId()+",soFarBytes:"+soFarBytes+",totalBytes:"+totalBytes+",percent:"+soFarBytes*1.0/totalBytes+",speed:"+task.getSpeed());
}
@Override
protected void blockComplete(BaseDownloadTask task) {
Log.d("feifei","blockComplete taskId:"+task.getId()+",filePath:"+task.getPath()+",fileName:"+task.getFilename()+",speed:"+task.getSpeed()+",isReuse:"+task.reuse());
}
@Override
protected void completed(BaseDownloadTask task) {
Log.d("feifei","completed taskId:"+task.getId()+",isReuse:"+task.reuse());
}
@Override
protected void paused(BaseDownloadTask task, int soFarBytes, int totalBytes) {
Log.d("feifei","paused taskId:"+task.getId()+",soFarBytes:"+soFarBytes+",totalBytes:"+totalBytes+",percent:"+soFarBytes*1.0/totalBytes);
}
@Override
protected void error(BaseDownloadTask task, Throwable e) {
Log.d("feifei","error taskId:"+task.getId()+",e:"+e.getLocalizedMessage());
}
@Override
protected void warn(BaseDownloadTask task) {
Log.d("feifei","warn taskId:"+task.getId());
}
});
singleTaskId = singleTask.start();
}
public void pause_single(){
Log.d("feifei","pause_single task:"+singleTaskId);
FileDownloader.getImpl().pause(singleTaskId);
}
public void delete_single(){
//刪除單個(gè)任務(wù)的database記錄
boolean deleteData = FileDownloader.getImpl().clear(singleTaskId,mSaveFolder);
File targetFile = new File(mSinglePath);
boolean delate = false;
if(targetFile.exists()){
delate = targetFile.delete();
}
Log.d("feifei","delete_single file,deleteDataBase:"+deleteData+",mSinglePath:"+mSinglePath+",delate:"+delate);
new File(FileDownloadUtils.getTempPath(mSinglePath)).delete();
}
多任務(wù)下載:
// 多任務(wù)下載
private FileDownloadListener downloadListener;
public FileDownloadListener createLis(){
return new FileDownloadSampleListener(){
@Override
protected void pending(BaseDownloadTask task, int soFarBytes, int totalBytes) {
if(task.getListener() != downloadListener){
return;
}
Log.d("feifei","pending taskId:"+task.getId()+",fileName:"+task.getFilename()+",soFarBytes:"+soFarBytes+",totalBytes:"+totalBytes+",percent:"+soFarBytes*1.0/totalBytes);
}
@Override
protected void progress(BaseDownloadTask task, int soFarBytes, int totalBytes) {
if(task.getListener() != downloadListener){
return;
}
Log.d("feifei","progress taskId:"+task.getId()+",fileName:"+task.getFilename()+",soFarBytes:"+soFarBytes+",totalBytes:"+totalBytes+",percent:"+soFarBytes*1.0/totalBytes+",speed:"+task.getSpeed());
}
@Override
protected void blockComplete(BaseDownloadTask task) {
if(task.getListener() != downloadListener){
return;
}
Log.d("feifei","blockComplete taskId:"+task.getId()+",filePath:"+task.getPath()+",fileName:"+task.getFilename()+",speed:"+task.getSpeed()+",isReuse:"+task.reuse());
}
@Override
protected void completed(BaseDownloadTask task) {
if(task.getListener() != downloadListener){
return;
}
Log.d("feifei","completed taskId:"+task.getId()+",isReuse:"+task.reuse());
}
@Override
protected void paused(BaseDownloadTask task, int soFarBytes, int totalBytes) {
if(task.getListener() != downloadListener){
return;
}
Log.d("feifei","paused taskId:"+task.getId()+",soFarBytes:"+soFarBytes+",totalBytes:"+totalBytes+",percent:"+soFarBytes*1.0/totalBytes);
}
@Override
protected void error(BaseDownloadTask task, Throwable e) {
if(task.getListener() != downloadListener){
return;
}
Log.d("feifei","error taskId:"+task.getId()+",e:"+e.getLocalizedMessage());
}
@Override
protected void warn(BaseDownloadTask task) {
if(task.getListener() != downloadListener){
return;
}
Log.d("feifei","warn taskId:"+task.getId());
}
};
}
public void start_multi(){
downloadListener = createLis();
//(1) 創(chuàng)建 FileDownloadQueueSet
final FileDownloadQueueSet queueSet = new FileDownloadQueueSet(downloadListener);
//(2) 創(chuàng)建Task 隊(duì)列
final List<BaseDownloadTask> tasks = new ArrayList<>();
BaseDownloadTask task1 = FileDownloader.getImpl().create(BIG_FILE_URLS[3]).setPath(mSaveFolder,true);
tasks.add(task1);
BaseDownloadTask task2 = FileDownloader.getImpl().create(BIG_FILE_URLS[4]).setPath(mSaveFolder,true);
tasks.add(task2);
//(3) 設(shè)置參數(shù)
// 每個(gè)任務(wù)的進(jìn)度 無(wú)回調(diào)
//queueSet.disableCallbackProgressTimes();
// do not want each task's download progress's callback,we just consider which task will completed.
queueSet.setCallbackProgressTimes(100);
queueSet.setCallbackProgressMinInterval(100);
//失敗 重試次數(shù)
queueSet.setAutoRetryTimes(3);
//避免掉幀
FileDownloader.enableAvoidDropFrame();
//(4)串行下載
queueSet.downloadSequentially(tasks);
//(5)任務(wù)啟動(dòng)
queueSet.start();
}
public void stop_multi(){
FileDownloader.getImpl().pause(downloadListener);
}
public void deleteAllFile(){
//清除所有的下載任務(wù)
FileDownloader.getImpl().clearAllTaskData();
//清除所有下載的文件
int count = 0;
File file = new File(FileDownloadUtils.getDefaultSaveRootPath());
do {
if (!file.exists()) {
break;
}
if (!file.isDirectory()) {
break;
}
File[] files = file.listFiles();
if (files == null) {
break;
}
for (File file1 : files) {
count++;
file1.delete();
}
} while (false);
Toast.makeText(this,
String.format("Complete delete %d files", count), Toast.LENGTH_LONG).show();
}
注意 FileDownloader默認(rèn)支持?jǐn)帱c(diǎn)續(xù)傳,如果想要重新從0開(kāi)始 重新下載,必須
- 將下載的文件和臨時(shí)文件刪除
new File(mSinglePath).delete();
new File(FileDownloadUtils.getTempPath(mSinglePath)).delete();
- 將數(shù)據(jù)庫(kù)的任務(wù)刪除
//清除所有的下載任務(wù)
FileDownloader.getImpl().clearAllTaskData();
//刪除單個(gè)任務(wù)的database記錄
boolean deleteData = FileDownloader.getImpl().clear(singleTaskId,mSaveFolder);