组合任务新增`unknownSize()`,用于处理组合任务大小未知的情况,https://github.com/AriaLyy/Aria/issues/380

v3.6.6
laoyuyu 6 years ago
parent 8c0ef0f879
commit 0c3e16cad7
  1. 32
      Aria/src/main/java/com/arialyy/aria/core/common/AbsThreadTask.java
  2. 7
      Aria/src/main/java/com/arialyy/aria/core/common/CompleteInfo.java
  3. 8
      Aria/src/main/java/com/arialyy/aria/core/common/StateConstance.java
  4. 15
      Aria/src/main/java/com/arialyy/aria/core/common/SubThreadConfig.java
  5. 10
      Aria/src/main/java/com/arialyy/aria/core/download/DGTaskWrapper.java
  6. 15
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTarget.java
  7. 4
      Aria/src/main/java/com/arialyy/aria/core/download/HttpGroupDelegate.java
  8. 2
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpFileInfoThread.java
  9. 2
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpFileInfoThread.java
  10. 2
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpThreadTask.java
  11. 1
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/SimpleDownloadUtil.java
  12. 10
      Aria/src/main/java/com/arialyy/aria/core/download/group/AbsGroupUtil.java
  13. 73
      Aria/src/main/java/com/arialyy/aria/core/download/group/DownloadGroupUtil.java
  14. 2
      Aria/src/main/java/com/arialyy/aria/core/download/group/FtpDirInfoThread.java
  15. 7
      Aria/src/main/java/com/arialyy/aria/core/download/group/SubDownloadLoader.java
  16. 3
      Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpFileInfoThread.java
  17. 2
      Aria/src/main/java/com/arialyy/aria/util/DbDataHelper.java
  18. 1
      DEV_LOG.md
  19. 8
      app/src/main/java/com/arialyy/simple/core/download/SingleTaskActivity.java
  20. 8
      app/src/main/java/com/arialyy/simple/core/download/group/DownloadGroupActivity.java
  21. 2
      build.gradle

@ -115,8 +115,7 @@ public abstract class AbsThreadTask<ENTITY extends AbsNormalEntity, TASK_WRAPPER
* @return {@code true}存活
*/
protected boolean isLive() {
Thread t = Thread.currentThread();
return !t.isInterrupted() && !isInterrupted;
return !Thread.currentThread().isInterrupted() && !isInterrupted;
}
/**
@ -399,19 +398,22 @@ public abstract class AbsThreadTask<ENTITY extends AbsNormalEntity, TASK_WRAPPER
* @param needRetry 是否可以重试
*/
private void retryThis(boolean needRetry) {
if (!NetUtils.isConnected(AriaManager.APP) && !isNotNetRetry) {
ALog.w(TAG, String.format("任务【%s】thread__%s__重试失败,网络未连接", mConfig.TEMP_FILE.getName(),
mConfig.THREAD_ID));
}
if (mFailTimes < RETRY_NUM && needRetry && (NetUtils.isConnected(AriaManager.APP)
|| isNotNetRetry) && !isBreak()) {
ALog.w(TAG,
String.format("任务【%s】thread__%s__正在重试", mConfig.TEMP_FILE.getName(), mConfig.THREAD_ID));
mFailTimes++;
handleRetryRecord();
ThreadTaskManager.getInstance().retryThread(AbsThreadTask.this);
} else {
handleFailState(!isBreak());
synchronized (AriaManager.LOCK) {
if (!NetUtils.isConnected(AriaManager.APP) && !isNotNetRetry) {
ALog.w(TAG, String.format("任务【%s】thread__%s__重试失败,网络未连接", mConfig.TEMP_FILE.getName(),
mConfig.THREAD_ID));
}
if (mFailTimes < RETRY_NUM && needRetry && (NetUtils.isConnected(AriaManager.APP)
|| isNotNetRetry) && !isBreak()) {
ALog.w(TAG,
String.format("任务【%s】thread__%s__正在重试", mConfig.TEMP_FILE.getName(),
mConfig.THREAD_ID));
mFailTimes++;
handleRetryRecord();
ThreadTaskManager.getInstance().retryThread(AbsThreadTask.this);
} else {
handleFailState(!isBreak());
}
}
}

@ -15,6 +15,8 @@
*/
package com.arialyy.aria.core.common;
import com.arialyy.aria.core.inf.AbsTaskWrapper;
/**
* Created by AriaL on 2018/3/3.
* 获取文件信息完成后 回调给下载线程的信息
@ -25,7 +27,10 @@ public class CompleteInfo {
*/
public int code;
public CompleteInfo(int code) {
public AbsTaskWrapper wrapper;
public CompleteInfo(int code, AbsTaskWrapper wrapper) {
this.code = code;
this.wrapper = wrapper;
}
}

@ -53,8 +53,8 @@ public class StateConstance {
* 所有子线程是否都已经停止
*/
public boolean isStop() {
//ALog.d(TAG, String.format("stop_num=%s; start_thread_num=%s; complete_num=%s", STOP_NUM,
// START_THREAD_NUM, COMPLETE_THREAD_NUM));
//ALog.d(TAG, String.format("stop_thread_num=%s; start_thread_num=%s; complete_thread_num=%s",
// STOP_NUM, START_THREAD_NUM, COMPLETE_THREAD_NUM));
return STOP_NUM == START_THREAD_NUM || STOP_NUM + COMPLETE_THREAD_NUM == START_THREAD_NUM;
}
@ -62,8 +62,8 @@ public class StateConstance {
* 所有子线程是否都已经失败
*/
public boolean isFail() {
//ALog.d(TAG, String.format("fail_num=%s; start_thread_num=%s; complete_num=%s", FAIL_NUM,
// START_THREAD_NUM, COMPLETE_THREAD_NUM));
//ALog.d(TAG, String.format("fail_thread_num=%s; start_thread_num=%s; complete_thread_num=%s",
// FAIL_NUM, START_THREAD_NUM, COMPLETE_THREAD_NUM));
return COMPLETE_THREAD_NUM != START_THREAD_NUM
&& (FAIL_NUM == START_THREAD_NUM || FAIL_NUM + COMPLETE_THREAD_NUM == START_THREAD_NUM);
}

@ -1,3 +1,18 @@
/*
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.aria.core.common;
import com.arialyy.aria.core.inf.AbsTaskWrapper;

@ -27,6 +27,8 @@ public class DGTaskWrapper extends AbsGroupTaskWrapper<DownloadGroupEntity, DTas
private List<DTaskWrapper> subTaskEntities;
private boolean unknownSize = false;
public DGTaskWrapper(DownloadGroupEntity entity) {
super(entity);
}
@ -36,6 +38,14 @@ public class DGTaskWrapper extends AbsGroupTaskWrapper<DownloadGroupEntity, DTas
this.subTaskEntities = subTaskEntities;
}
public boolean isUnknownSize() {
return unknownSize;
}
public void setUnknownSize(boolean unknownSize) {
this.unknownSize = unknownSize;
}
/**
* 组名
*/

@ -78,7 +78,7 @@ public class DownloadGroupTarget extends AbsDGTarget<DownloadGroupTarget> implem
* 任务组总任务大小任务组是一个抽象的概念没有真实的数据实体任务组的大小是Aria动态获取子任务大小相加而得到的
* 如果你知道当前任务组总大小你也可以调用该方法给任务组设置大小
*
* 为了更好的用户体验组合任务必须设置文件大小
* 为了更好的用户体验组合任务最好设置文件大小默认需要强制设置文件大小如果无法获取到总长度请调用{@link #unknownSize()}
*
* @param fileSize 任务组总大小
*/
@ -94,6 +94,19 @@ public class DownloadGroupTarget extends AbsDGTarget<DownloadGroupTarget> implem
return this;
}
/**
* 如果无法获取到组合任务到总长度请调用该方法
* 请注意
* 1如果组合任务到子任务数过多请不要使用该标志位否则Aria将需要消耗大量的时间获取组合任务的总长度
* 2如果你的知道组合任务的总长度请使用{@link #setFileSize(long)}设置组合任务的长度
* 3由于网络或其它原因的存在这种方式获取的组合任务大小有可能是不准确的
*/
@CheckResult
public DownloadGroupTarget unknownSize() {
getTaskWrapper().setUnknownSize(true);
return this;
}
/**
* 如果你是使用{@link DownloadReceiver#load(DownloadGroupEntity)}进行下载操作那么你需要设置任务组的下载地址
*/

@ -114,8 +114,8 @@ class HttpGroupDelegate extends AbsGroupDelegate<DownloadGroupTarget> {
return false;
}
if (getTaskWrapper().getEntity().getFileSize() == 0) {
ALog.e(TAG, "组合任务必须设置文件文件大小");
if (!getTaskWrapper().isUnknownSize() && getTaskWrapper().getEntity().getFileSize() == 0) {
ALog.e(TAG, "组合任务必须设置文件文件大小,默认需要强制设置文件大小。如果无法获取到总长度,请调用#unknownSize()来标志该组合任务");
return false;
}

@ -55,6 +55,6 @@ class FtpFileInfoThread extends AbsFtpInfoThread<DownloadEntity, DTaskWrapper> {
mTaskWrapper.setNewTask(true);
}
mEntity.setFileSize(mSize);
mCallback.onComplete(mEntity.getUrl(), new CompleteInfo(code));
mCallback.onComplete(mEntity.getUrl(), new CompleteInfo(code, mTaskWrapper));
}
}

@ -220,7 +220,7 @@ public class HttpFileInfoThread implements Runnable {
if (end) {
mTaskDelegate.setChunked(isChunked);
if (onFileInfoCallback != null) {
CompleteInfo info = new CompleteInfo(code);
CompleteInfo info = new CompleteInfo(code, mTaskWrapper);
onFileInfoCallback.onComplete(mEntity.getUrl(), info);
}
mEntity.update();

@ -29,7 +29,6 @@ import com.arialyy.aria.exception.TaskException;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.BufferedRandomAccessFile;
import java.io.BufferedInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
@ -44,7 +43,6 @@ import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.util.Map;
import java.util.Set;
import java.util.zip.GZIPInputStream;
/**
* Created by lyy on 2017/1/18. 下载线程

@ -107,6 +107,7 @@ public class SimpleDownloadUtil implements IUtil, Runnable {
if (isStop || isCancel) {
return;
}
// 如果网址没有变,而服务器端端文件改变,以下代码就没有用了
//if (mTaskWrapper.getEntity().getFileSize() <= 1
// || mTaskWrapper.isRefreshInfo()
// || mTaskWrapper.getRequestType() == AbsTaskWrapper.D_FTP

@ -288,7 +288,15 @@ public abstract class AbsGroupUtil implements IUtil, Runnable {
* 创建并启动子任务下载器
*/
SubDownloadLoader createSubLoader(DTaskWrapper taskWrapper) {
SubDownloadLoader loader = new SubDownloadLoader(mScheduler, taskWrapper);
return createSubLoader(taskWrapper, true);
}
/**
* 创建并启动子任务下载器
* @param needGetFileInfo {@code true} 需要获取文件信息{@code false} 不需要获取文件信息
*/
SubDownloadLoader createSubLoader(DTaskWrapper taskWrapper, boolean needGetFileInfo) {
SubDownloadLoader loader = new SubDownloadLoader(mScheduler, taskWrapper, needGetFileInfo);
mExeLoader.put(loader.getKey(), loader);
mSubQueue.startTask(loader);
return loader;

@ -15,16 +15,26 @@
*/
package com.arialyy.aria.core.download.group;
import com.arialyy.aria.core.common.CompleteInfo;
import com.arialyy.aria.core.common.IUtil;
import com.arialyy.aria.core.common.OnFileInfoCallback;
import com.arialyy.aria.core.download.DGTaskWrapper;
import com.arialyy.aria.core.download.DTaskWrapper;
import com.arialyy.aria.core.download.downloader.HttpFileInfoThread;
import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.exception.BaseException;
import com.arialyy.aria.util.ALog;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Created by AriaL on 2017/6/30.
* 任务组下载工具
*/
public class DownloadGroupUtil extends AbsGroupUtil implements IUtil {
private static final String TAG = "DownloadGroupUtil";
private final Object LOCK = new Object();
private ExecutorService mPool = null;
public DownloadGroupUtil(IDownloadGroupListener listener, DGTaskWrapper taskWrapper) {
super(listener, taskWrapper);
@ -47,11 +57,68 @@ public class DownloadGroupUtil extends AbsGroupUtil implements IUtil {
if (mState.getCompleteNum() == mState.getSubSize()) {
mListener.onComplete();
} else {
for (DTaskWrapper wrapper : mGTWrapper.getSubTaskWrapper()) {
if (wrapper.getState() != IEntity.STATE_COMPLETE) {
createSubLoader(wrapper);
// 处理组合任务大小未知的情况
if (mGTWrapper.isUnknownSize() && mGTWrapper.getEntity().getFileSize() < 1) {
mPool = Executors.newCachedThreadPool();
getGroupSize();
try {
synchronized (LOCK) {
LOCK.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
for (DTaskWrapper wrapper : mGTWrapper.getSubTaskWrapper()) {
if (wrapper.getState() != IEntity.STATE_COMPLETE) {
createSubLoader(wrapper);
}
}
}
}
}
/**
* 获取组合任务大小使用该方式获取到的组合任务大小子任务不需要再重新获取文件大小
*/
private void getGroupSize() {
new Thread(new Runnable() {
int count;
@Override public void run() {
for (DTaskWrapper dTaskWrapper : mGTWrapper.getSubTaskWrapper()) {
mPool.submit(new HttpFileInfoThread(dTaskWrapper, new OnFileInfoCallback() {
@Override public void onComplete(String url, CompleteInfo info) {
createSubLoader((DTaskWrapper) info.wrapper, false);
count++;
checkGetSizeComplete(count);
}
@Override public void onFail(String url, BaseException e, boolean needRetry) {
ALog.e(TAG, String.format("获取文件信息失败,url:%s", url));
count++;
checkGetSizeComplete(count);
}
}));
}
}
}).start();
}
/**
* 检查组合任务大小是否获取完成获取完成后取消阻塞并设置组合任务大小
*/
private void checkGetSizeComplete(int count) {
if (count == mGTWrapper.getSubTaskWrapper().size()) {
long size = 0;
for (DTaskWrapper wrapper : mGTWrapper.getSubTaskWrapper()) {
size += wrapper.getEntity().getFileSize();
}
mGTWrapper.getEntity().setFileSize(size);
synchronized (LOCK) {
LOCK.notify();
}
}
}
}

@ -50,7 +50,7 @@ class FtpDirInfoThread extends AbsFtpInfoThread<DownloadGroupEntity, DGTaskWrapp
@Override protected void onPreComplete(int code) {
super.onPreComplete(code);
mEntity.setFileSize(mSize);
mCallback.onComplete(mEntity.getKey(), new CompleteInfo(code));
mCallback.onComplete(mEntity.getKey(), new CompleteInfo(code, mTaskWrapper));
}
/**

@ -19,6 +19,7 @@ import android.os.Handler;
import com.arialyy.aria.core.common.CompleteInfo;
import com.arialyy.aria.core.common.IUtil;
import com.arialyy.aria.core.common.OnFileInfoCallback;
import com.arialyy.aria.core.download.DGTaskWrapper;
import com.arialyy.aria.core.download.DTaskWrapper;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.downloader.Downloader;
@ -39,7 +40,11 @@ class SubDownloadLoader implements IUtil {
private Handler mSchedulers;
private ChildDownloadListener mListener;
SubDownloadLoader(Handler schedulers, DTaskWrapper taskWrapper) {
/**
* @param schedulers 调度器
* @param needGetInfo {@code true} 需要获取文件信息{@code false} 不需要获取文件信息
*/
SubDownloadLoader(Handler schedulers, DTaskWrapper taskWrapper, boolean needGetInfo) {
mWrapper = taskWrapper;
mSchedulers = schedulers;
mListener = new ChildDownloadListener(mSchedulers, SubDownloadLoader.this);

@ -95,6 +95,7 @@ class FtpFileInfoThread extends AbsFtpInfoThread<UploadEntity, UTaskWrapper> {
@Override protected void onPreComplete(int code) {
super.onPreComplete(code);
mCallback.onComplete(mEntity.getKey(), new CompleteInfo(isComplete ? CODE_COMPLETE : code));
mCallback.onComplete(mEntity.getKey(),
new CompleteInfo(isComplete ? CODE_COMPLETE : code, mTaskWrapper));
}
}

@ -56,7 +56,7 @@ public class DbDataHelper {
DbEntity.findRelationData(DGEntityWrapper.class, "DownloadGroupEntity.groupHash=?",
groupHash);
return wrapper == null ? null : wrapper.get(0).groupEntity;
return wrapper == null || wrapper.size() == 0 ? null : wrapper.get(0).groupEntity;
}
/**

@ -10,6 +10,7 @@
- fix bug https://github.com/AriaLyy/Aria/issues/388
- 修复使用`Content-Disposition`的文件名时,第一次下载无法重命名文件的问题
- 修复使用`Content-Disposition`的文件名时,多次重命名文件的问题
- 组合任务新增`unknownSize()`,用于处理组合任务大小未知的情况,https://github.com/AriaLyy/Aria/issues/380
+ v_3.6.3 (2019/4/2)
- fix bug https://github.com/AriaLyy/Aria/issues/377
+ v_3.6.2 (2019/4/1)

@ -59,9 +59,9 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
//"http://120.55.95.61:8811/ghcg/zg/武义总规纲要成果.zip";
//"https://yizi-kejian.oss-cn-beijing.aliyuncs.com/qimeng/package1/qmtable11.zip";
//"http://rs.0.gaoshouyou.com/d/04/1e/400423a7551e1f3f0eb1812afa1f9b44.apk";
//"http://chargepile2.techsum.net/car-manage/file/download?path=2019-04-26/c0242efd18be4ecbb23911b1c509dcad--掌通各系统汇总.xls"; // 无长度的chunked
"http://chargepile2.techsum.net/car-manage/file/download?path=2019-04-26/c0242efd18be4ecbb23911b1c509dcad--掌通各系统汇总.xls"; // 无长度的chunked
//"http://58.210.9.131/tpk/sipgt//TDLYZTGH.tpk"; //chunked 下载
"http://apk500.bce.baidu-mgame.com/game/67000/67734/20170622040827_oem_5502845.apk?r=1";
//"http://apk500.bce.baidu-mgame.com/game/67000/67734/20170622040827_oem_5502845.apk?r=1";
//"https://dl.genymotion.com/releases/genymotion-2.12.1/genymotion-2.12.1-vbox.exe";
//"http://9.9.9.50:5000/download/CentOS-7-x86_64-Minimal-1804.iso";
//"http://v2.qingdian1.com/m_20180730_991/2/2B9FB34A4BCD8CE61481D1C8418EFE36_1080P.m3u8";
@ -316,8 +316,8 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
Aria.download(SingleTaskActivity.this)
.load(DOWNLOAD_URL)
//.addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3")
.addHeader("Accept-Encoding", "gzip, deflate")
.addHeader("DNT", "1")
//.addHeader("Accept-Encoding", "gzip, deflate")
//.addHeader("DNT", "1")
//.addHeader("Cookie", "BAIDUID=648E5FF020CC69E8DD6F492D1068AAA9:FG=1; BIDUPSID=648E5FF020CC69E8DD6F492D1068AAA9; PSTM=1519099573; BD_UPN=12314753; locale=zh; BDSVRTM=0")
.useServerFileName(true)
.setFilePath(path, true)

@ -24,14 +24,12 @@ import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadGroupEntity;
import com.arialyy.aria.core.download.DownloadGroupTask;
import com.arialyy.aria.core.download.DGTaskWrapper;
import com.arialyy.frame.util.show.L;
import com.arialyy.frame.util.show.T;
import com.arialyy.simple.R;
import com.arialyy.simple.base.BaseActivity;
import com.arialyy.simple.databinding.ActivityDownloadGroupBinding;
import com.arialyy.simple.widget.SubStateLinearLayout;
import java.util.ArrayList;
import java.util.List;
/**
@ -80,9 +78,6 @@ public class DownloadGroupActivity extends BaseActivity<ActivityDownloadGroupBin
public void onClick(View view) {
switch (view.getId()) {
case R.id.start:
List<String> temp = new ArrayList<>();
temp.add(
"https://d.pcs.baidu.com/file/130335545f3f4d9cc38afe709c19af5a?fid=1411168371-250528-1010657263806840&dstime=1531134714&rt=sh&sign=FDtAERVY-DCb740ccc5511e5e8fedcff06b081203-h8KgJ6gl4oY9UR6NqvwJsT4nVSM%3D&expires=8h&chkv=1&chkbd=0&chkpc=et&dp-logid=4401996296756616039&dp-callid=0&r=279987343");
Aria.download(this)
.loadGroup(mUrls)
.setDirPath(
@ -91,7 +86,8 @@ public class DownloadGroupActivity extends BaseActivity<ActivityDownloadGroupBin
.setGroupAlias("任务组测试")
//.setSubFileName(getModule(GroupModule.class).getSubName2())
.setSubFileName(getModule(GroupModule.class).getSubName())
.setFileSize(114981416)
.unknownSize()
//.setFileSize(114981416)
//.updateUrls(temp)
.start();
break;

@ -43,7 +43,7 @@ task clean(type: Delete) {
ext {
userOrg = 'arialyy'
groupId = 'com.arialyy.aria'
publishVersion = '3.6.4_dev_1'
publishVersion = '3.6.4_dev_2'
// publishVersion = '1.0.4' //FTP插件
repoName='maven'
desc = 'android 下载框架'

Loading…
Cancel
Save