|
|
@ -15,6 +15,7 @@ |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
package com.arialyy.aria.core.download.downloader; |
|
|
|
package com.arialyy.aria.core.download.downloader; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import android.util.SparseArray; |
|
|
|
import com.arialyy.aria.core.download.DownloadEntity; |
|
|
|
import com.arialyy.aria.core.download.DownloadEntity; |
|
|
|
import com.arialyy.aria.core.download.DownloadGroupTaskEntity; |
|
|
|
import com.arialyy.aria.core.download.DownloadGroupTaskEntity; |
|
|
|
import com.arialyy.aria.core.download.DownloadTaskEntity; |
|
|
|
import com.arialyy.aria.core.download.DownloadTaskEntity; |
|
|
@ -24,12 +25,14 @@ import java.io.File; |
|
|
|
import java.util.HashMap; |
|
|
|
import java.util.HashMap; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Set; |
|
|
|
import java.util.Set; |
|
|
|
|
|
|
|
import java.util.Timer; |
|
|
|
|
|
|
|
import java.util.TimerTask; |
|
|
|
import java.util.concurrent.ExecutorService; |
|
|
|
import java.util.concurrent.ExecutorService; |
|
|
|
import java.util.concurrent.Executors; |
|
|
|
import java.util.concurrent.Executors; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Created by AriaL on 2017/6/30. |
|
|
|
* Created by AriaL on 2017/6/30. |
|
|
|
* 下载组工具 |
|
|
|
* 任务组下载工具 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public class DownloadGroupUtil implements IDownloadUtil { |
|
|
|
public class DownloadGroupUtil implements IDownloadUtil { |
|
|
|
private static final String TAG = "DownloadGroupUtil"; |
|
|
|
private static final String TAG = "DownloadGroupUtil"; |
|
|
@ -43,6 +46,15 @@ public class DownloadGroupUtil implements IDownloadUtil { |
|
|
|
private IDownloadListener mListener; |
|
|
|
private IDownloadListener mListener; |
|
|
|
private DownloadGroupTaskEntity mTaskEntity; |
|
|
|
private DownloadGroupTaskEntity mTaskEntity; |
|
|
|
private boolean isRunning = true; |
|
|
|
private boolean isRunning = true; |
|
|
|
|
|
|
|
private Timer mTimer; |
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* 初始化完成的任务书数 |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
private int mInitNum = 0; |
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* 初始化失败的任务数 |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
private int mFailNum = 0; |
|
|
|
/** |
|
|
|
/** |
|
|
|
* 保存所有没有下载完成的任务,key为下载地址 |
|
|
|
* 保存所有没有下载完成的任务,key为下载地址 |
|
|
|
*/ |
|
|
|
*/ |
|
|
@ -58,10 +70,16 @@ public class DownloadGroupUtil implements IDownloadUtil { |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private Map<String, DownloadThreader> mDownloaderMap = new HashMap<>(); |
|
|
|
private Map<String, DownloadThreader> mDownloaderMap = new HashMap<>(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* 文件信息回调组 |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
private SparseArray<FileInfoThread.OnFileInfoCallback> mFileInfoCallbacks = new SparseArray<>(); |
|
|
|
|
|
|
|
|
|
|
|
DownloadGroupUtil(IDownloadListener listener, DownloadGroupTaskEntity taskEntity) { |
|
|
|
DownloadGroupUtil(IDownloadListener listener, DownloadGroupTaskEntity taskEntity) { |
|
|
|
mListener = listener; |
|
|
|
mListener = listener; |
|
|
|
mTaskEntity = taskEntity; |
|
|
|
mTaskEntity = taskEntity; |
|
|
|
mInfoPool = Executors.newCachedThreadPool(); |
|
|
|
mInfoPool = Executors.newCachedThreadPool(); |
|
|
|
|
|
|
|
mExePool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); |
|
|
|
|
|
|
|
|
|
|
|
for (DownloadEntity entity : mTaskEntity.entity.getChild()) { |
|
|
|
for (DownloadEntity entity : mTaskEntity.entity.getChild()) { |
|
|
|
File file = new File(entity.getDownloadPath()); |
|
|
|
File file = new File(entity.getDownloadPath()); |
|
|
@ -88,9 +106,13 @@ public class DownloadGroupUtil implements IDownloadUtil { |
|
|
|
|
|
|
|
|
|
|
|
@Override public void cancelDownload() { |
|
|
|
@Override public void cancelDownload() { |
|
|
|
isRunning = false; |
|
|
|
isRunning = false; |
|
|
|
|
|
|
|
closeTimer(); |
|
|
|
if (!mInfoPool.isShutdown()) { |
|
|
|
if (!mInfoPool.isShutdown()) { |
|
|
|
mInfoPool.shutdown(); |
|
|
|
mInfoPool.shutdown(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (!mExePool.isShutdown()) { |
|
|
|
|
|
|
|
mExePool.shutdown(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Set<String> keys = mDownloaderMap.keySet(); |
|
|
|
Set<String> keys = mDownloaderMap.keySet(); |
|
|
|
for (String key : keys) { |
|
|
|
for (String key : keys) { |
|
|
@ -103,9 +125,13 @@ public class DownloadGroupUtil implements IDownloadUtil { |
|
|
|
|
|
|
|
|
|
|
|
@Override public void stopDownload() { |
|
|
|
@Override public void stopDownload() { |
|
|
|
isRunning = false; |
|
|
|
isRunning = false; |
|
|
|
|
|
|
|
closeTimer(); |
|
|
|
if (!mInfoPool.isShutdown()) { |
|
|
|
if (!mInfoPool.isShutdown()) { |
|
|
|
mInfoPool.shutdown(); |
|
|
|
mInfoPool.shutdown(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (!mExePool.isShutdown()) { |
|
|
|
|
|
|
|
mExePool.shutdown(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Set<String> keys = mDownloaderMap.keySet(); |
|
|
|
Set<String> keys = mDownloaderMap.keySet(); |
|
|
|
for (String key : keys) { |
|
|
|
for (String key : keys) { |
|
|
@ -119,9 +145,28 @@ public class DownloadGroupUtil implements IDownloadUtil { |
|
|
|
@Override public void startDownload() { |
|
|
|
@Override public void startDownload() { |
|
|
|
isRunning = true; |
|
|
|
isRunning = true; |
|
|
|
Set<String> keys = mExeMap.keySet(); |
|
|
|
Set<String> keys = mExeMap.keySet(); |
|
|
|
|
|
|
|
mListener.onPre(); |
|
|
|
for (String key : keys) { |
|
|
|
for (String key : keys) { |
|
|
|
DownloadTaskEntity taskEntity = mExeMap.get(key); |
|
|
|
DownloadTaskEntity taskEntity = mExeMap.get(key); |
|
|
|
mInfoPool.execute(new FileInfoThread(taskEntity, new FileInfoThread.OnFileInfoCallback() { |
|
|
|
if (taskEntity != null) { |
|
|
|
|
|
|
|
mInfoPool.execute(createFileInfoThread(taskEntity)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override public void resumeDownload() { |
|
|
|
|
|
|
|
startDownload(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* 创建文件信息获取线程 |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
private FileInfoThread createFileInfoThread(DownloadTaskEntity taskEntity) { |
|
|
|
|
|
|
|
FileInfoThread.OnFileInfoCallback callback = mFileInfoCallbacks.get(taskEntity.hashCode()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (callback == null) { |
|
|
|
|
|
|
|
callback = new FileInfoThread.OnFileInfoCallback() { |
|
|
|
|
|
|
|
int failNum = 0; |
|
|
|
|
|
|
|
|
|
|
|
@Override public void onComplete(String url, int code) { |
|
|
|
@Override public void onComplete(String url, int code) { |
|
|
|
DownloadTaskEntity te = mExeMap.get(url); |
|
|
|
DownloadTaskEntity te = mExeMap.get(url); |
|
|
@ -129,18 +174,53 @@ public class DownloadGroupUtil implements IDownloadUtil { |
|
|
|
mTotalSize += te.getEntity().getFileSize(); |
|
|
|
mTotalSize += te.getEntity().getFileSize(); |
|
|
|
startChildDownload(te); |
|
|
|
startChildDownload(te); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
mInitNum++; |
|
|
|
|
|
|
|
if (mInitNum + mFailNum == mTaskEntity.getEntity().getChild().size()) { |
|
|
|
|
|
|
|
startRunningFlow(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override public void onFail(String url, String errorMsg) { |
|
|
|
@Override public void onFail(String url, String errorMsg) { |
|
|
|
mFailMap.put(url, mExeMap.get(url)); |
|
|
|
DownloadTaskEntity te = mExeMap.get(url); |
|
|
|
|
|
|
|
if (te != null) { |
|
|
|
|
|
|
|
mFailMap.put(url, te); |
|
|
|
|
|
|
|
mFileInfoCallbacks.put(te.hashCode(), this); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
mFailNum++; |
|
|
|
|
|
|
|
failNum++; |
|
|
|
|
|
|
|
if (failNum < 10){ |
|
|
|
|
|
|
|
mInfoPool.execute(createFileInfoThread(te)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (mInitNum + mFailNum == mTaskEntity.getEntity().getChild().size()) { |
|
|
|
|
|
|
|
startRunningFlow(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
})); |
|
|
|
}; |
|
|
|
} |
|
|
|
} |
|
|
|
mListener.onPostPre(mTotalSize); |
|
|
|
|
|
|
|
|
|
|
|
return new FileInfoThread(taskEntity, callback); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override public void resumeDownload() { |
|
|
|
private void closeTimer() { |
|
|
|
startDownload(); |
|
|
|
if (mTimer != null) { |
|
|
|
|
|
|
|
mTimer.purge(); |
|
|
|
|
|
|
|
mTimer.cancel(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* 开始进度流程 |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
private void startRunningFlow() { |
|
|
|
|
|
|
|
mListener.onPostPre(mTotalSize); |
|
|
|
|
|
|
|
mListener.onStart(mCurrentProgress); |
|
|
|
|
|
|
|
closeTimer(); |
|
|
|
|
|
|
|
mTimer = new Timer(true); |
|
|
|
|
|
|
|
mTimer.schedule(new TimerTask() { |
|
|
|
|
|
|
|
@Override public void run() { |
|
|
|
|
|
|
|
mListener.onProgress(mCurrentProgress); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, 1000); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
@ -177,9 +257,6 @@ public class DownloadGroupUtil implements IDownloadUtil { |
|
|
|
|
|
|
|
|
|
|
|
DownloadTaskEntity taskEntity; |
|
|
|
DownloadTaskEntity taskEntity; |
|
|
|
DownloadEntity entity; |
|
|
|
DownloadEntity entity; |
|
|
|
long lastLen = 0; //上一次发送长度
|
|
|
|
|
|
|
|
long lastTime = 0; |
|
|
|
|
|
|
|
long INTERVAL_TIME = 1000; //1m更新周期
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ChildDownloadListener(DownloadTaskEntity entity) { |
|
|
|
ChildDownloadListener(DownloadTaskEntity entity) { |
|
|
|
this.taskEntity = entity; |
|
|
|
this.taskEntity = entity; |
|
|
@ -204,13 +281,7 @@ public class DownloadGroupUtil implements IDownloadUtil { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override public void onProgress(long currentLocation) { |
|
|
|
@Override public void onProgress(long currentLocation) { |
|
|
|
if (System.currentTimeMillis() - lastTime > INTERVAL_TIME) { |
|
|
|
mCurrentProgress += currentLocation; |
|
|
|
long speed = currentLocation - lastLen; |
|
|
|
|
|
|
|
lastTime = System.currentTimeMillis(); |
|
|
|
|
|
|
|
handleSpeed(speed); |
|
|
|
|
|
|
|
entity.setCurrentProgress(currentLocation); |
|
|
|
|
|
|
|
lastLen = currentLocation; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override public void onStop(long stopLocation) { |
|
|
|
@Override public void onStop(long stopLocation) { |
|
|
|