优化下载文件的完整性

pull/330/head
laoyuyu 6 years ago
parent ce77477b09
commit 8201eef571
  1. 48
      Aria/src/main/java/com/arialyy/aria/core/common/AbsFileer.java
  2. 2
      Aria/src/main/java/com/arialyy/aria/core/common/ProxyHelper.java
  3. 6
      Aria/src/main/java/com/arialyy/aria/core/common/StateConstance.java
  4. 4
      Aria/src/main/java/com/arialyy/aria/core/download/BaseNormalTarget.java
  5. 24
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpThreadTask.java
  6. 2
      Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java
  7. 4
      app/src/main/AndroidManifest.xml
  8. 6
      app/src/main/java/com/arialyy/simple/download/group/DownloadGroupActivity.java
  9. 74
      app/src/main/java/com/arialyy/simple/download/group/GroupModule.java
  10. 7
      app/src/main/java/com/arialyy/simple/test/AnyRunActivity.java
  11. 2
      app/src/main/java/com/arialyy/simple/test/AnyRunnModule.java

@ -245,7 +245,7 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
}
for (int i = 0; i < mStartThreadNum; i++) {
AbsThreadTask task = mTask.get(i);
if (task != null) {
if (task != null && !task.isThreadComplete()) {
task.stop();
}
}
@ -281,6 +281,9 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
if (mRecord.threadRecords == null || mRecord.threadRecords.isEmpty()) {
initRecord(true);
} else if (mRecord.isBlock) {
final int threadNum = mRecord.threadRecords.size();
final long blockLen = mEntity.getFileSize() / threadNum;
int i = 0;
for (ThreadRecord tr : mRecord.threadRecords) {
File temp = new File(String.format(SUB_PATH, mRecord.filePath, tr.threadId));
if (!temp.exists()) {
@ -292,16 +295,37 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
if (tr.isComplete) {
mCompleteThreadNum++;
} else {
mStartThreadNum++;
long realLocation = i * blockLen + temp.length();
ALog.w(TAG, String.format(
"startLocation = %s; endLocation = %s; block = %s; tempLen = %s; i = %s",
tr.startLocation, tr.endLocation, blockLen, temp.length(), i));
if (tr.endLocation == realLocation) {
ALog.d(TAG, String.format("分块【%s】已完成,更新记录", temp.getPath()));
tr.startLocation = realLocation;
tr.isComplete = true;
mCompleteThreadNum++;
} else {
tr.isComplete = false;
if (realLocation < tr.startLocation) {
ALog.w(TAG, String.format("修正分块【%s】的进度记录为:%s", temp.getPath(), realLocation));
tr.startLocation = realLocation;
} else if (realLocation > tr.endLocation) {
ALog.w(TAG, String.format("分块【%s】错误,将重新开始该分块", temp.getPath()));
temp.delete();
tr.startLocation = i * blockLen;
}
mStartThreadNum++;
}
}
}
mTotalThreadNum = mRecord.threadRecords.size();
mTaskEntity.setNewTask(false);
i++;
}
mTotalThreadNum = mRecord.threadRecords.size();
mTaskEntity.setNewTask(false);
} else {
File file = new File(mRecord.filePath);
if (!file.exists()) {
ALog.w(TAG, String.format("下载文件【%s】不存在,任务将重新开始", file.getPath()));
ALog.w(TAG, String.format("文件【%s】不存在,任务将重新开始", file.getPath()));
mRecord.deleteData();
initRecord(true);
return;
@ -483,22 +507,24 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
}
//如果有记录,则恢复任务
if (tr.startLocation >= 0) {
Long r = tr.startLocation;
if (tr.startLocation > 0) {
long r = tr.startLocation;
//记录的位置需要在线程区间中
if (startL < r && r < (i == (mTotalThreadNum - 1) ? fileLength : endL)) {
if (startL < r && r <= (i == (mTotalThreadNum - 1) ? fileLength : endL)) {
mConstance.CURRENT_LOCATION += r - startL;
startL = r;
}
ALog.d(TAG, String.format("任务【%s】线程__%s__恢复任务", mEntity.getFileName(), i));
} else {
tr.startLocation = startL;
}
//最后一个线程的结束位置即为文件的总长度
if (i == (mTotalThreadNum - 1)) {
endL = fileLength;
}
// 更新记录
tr.startLocation = startL;
tr.endLocation = endL;
if (tr.endLocation <= 0) {
tr.endLocation = endL;
}
if (isNewTr) {
mRecord.threadRecords.add(tr);
}

@ -47,7 +47,7 @@ public class ProxyHelper {
}
private void init() {
List<String> classes = CommonUtil.getClassName(AriaManager.APP,
List<String> classes = CommonUtil.getPkgClassNames(AriaManager.APP,
"com.arialyy.aria.ProxyClassCounter");
for (String className : classes) {
count(className);

@ -50,14 +50,16 @@ public class StateConstance {
* 所有子线程是否都已经停止
*/
public boolean isStop() {
return STOP_NUM == START_THREAD_NUM;
ALog.d(TAG, String.format("stop_num=%s; start_thread_num=%s; complete_num=%s", STOP_NUM,
START_THREAD_NUM, COMPLETE_THREAD_NUM));
return STOP_NUM == START_THREAD_NUM || STOP_NUM + COMPLETE_THREAD_NUM == START_THREAD_NUM;
}
/**
* 所有子线程是否都已经失败
*/
public boolean isFail() {
ALog.d(TAG, String.format("fail_num=%s; start_thread_num=%s, complete_num=%s", FAIL_NUM,
ALog.d(TAG, String.format("fail_num=%s; start_thread_num=%s; complete_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);

@ -162,7 +162,7 @@ abstract class BaseNormalTarget<TARGET extends BaseNormalTarget>
}
}
//设置文件保存路径,如果新文件路径和文件路径不同,则修改路径
//设置文件保存路径,如果新文件路径和文件路径不同,则修改路径
if (!filePath.equals(mEntity.getDownloadPath())) {
if (DbEntity.checkDataExist(DownloadEntity.class, "downloadPath=?", filePath)) {
ALog.e(TAG, "下载失败,保存路径【" + filePath + "】已经被其它任务占用,请设置其它保存路径");
@ -200,7 +200,7 @@ abstract class BaseNormalTarget<TARGET extends BaseNormalTarget>
ALog.e(TAG, "下载失败,url【" + url + "】不合法");
return false;
}
if (!TextUtils.isEmpty(newUrl)){
if (!TextUtils.isEmpty(newUrl)) {
mEntity.setUrl(newUrl);
mTaskEntity.setUrl(newUrl);
}

@ -76,7 +76,6 @@ final class HttpThreadTask extends AbsThreadTask<DownloadEntity, DownloadTaskEnt
ALog.d(TAG,
String.format("任务【%s】线程__%s__开始下载【开始位置 : %s,结束位置:%s】", mConfig.TEMP_FILE.getName(),
mConfig.THREAD_ID, mConfig.START_LOCATION, mConfig.END_LOCATION));
//在头里面请求下载开始位置和结束位置
conn.setRequestProperty("Range",
String.format("bytes=%s-%s", mConfig.START_LOCATION, (mConfig.END_LOCATION - 1)));
} else {
@ -144,10 +143,24 @@ final class HttpThreadTask extends AbsThreadTask<DownloadEntity, DownloadTaskEnt
if (mSleepTime > 0) {
Thread.sleep(mSleepTime);
}
bf.flip();
foc.write(bf);
bf.compact();
progress(len);
//
//bf.flip();
//foc.write(bf);
//bf.compact();
//progress(len);
if (mChildCurrentLocation + len >= mConfig.END_LOCATION) {
len = (int) (mConfig.END_LOCATION - mChildCurrentLocation);
bf.flip();
fos.write(bf.array(), 0, len);
bf.compact();
progress(len);
break;
} else {
bf.flip();
foc.write(bf);
bf.compact();
progress(len);
}
}
handleComplete();
} catch (InterruptedException e) {
@ -157,6 +170,7 @@ final class HttpThreadTask extends AbsThreadTask<DownloadEntity, DownloadTaskEnt
} finally {
try {
if (fos != null) {
fos.flush();
fos.close();
}
if (foc != null) {

@ -77,7 +77,7 @@ public class CommonUtil {
* @param className 过滤的类名
* @return 类的完整名称
*/
public static List<String> getClassName(Context context, String className) {
public static List<String> getPkgClassNames(Context context, String className) {
List<String> classNameList = new ArrayList<>();
String pPath = context.getPackageCodePath();
File dir = new File(pPath).getParentFile();

@ -16,10 +16,10 @@
<!--android:name=".test.TestActivity"-->
<!--android:name=".test.AnyRunActivity"-->
<!--android:name=".test.TestGroupActivity"-->
<!--android:name=".MainActivity"-->
<!--android:name="com.arialyy.simple.test.AnyRunActivity"-->
<!--android:name=".download.group.DownloadGroupActivity"-->
<activity
android:name=".MainActivity"
android:name=".download.group.DownloadGroupActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>

@ -45,7 +45,7 @@ public class DownloadGroupActivity extends BaseActivity<ActivityDownloadGroupBin
super.init(savedInstanceState);
Aria.download(this).register();
setTitle("任务组");
mUrls = getModule(GroupModule.class).getUrls();
mUrls = getModule(GroupModule.class).getUrls2();
DownloadGroupTaskEntity entity = Aria.download(this).getGroupTask(mUrls);
if (entity != null && entity.getEntity() != null) {
DownloadGroupEntity groupEntity = entity.getEntity();
@ -82,9 +82,9 @@ public class DownloadGroupActivity extends BaseActivity<ActivityDownloadGroupBin
Aria.download(this)
.loadGroup(mUrls)
.setDirPath(
Environment.getExternalStorageDirectory().getPath() + "/Download/group_test_3")
Environment.getExternalStorageDirectory().getPath() + "/Download/group_test_5")
.setGroupAlias("任务组测试")
//.setSubFileName(getModule(GroupModule.class).getSubName())
.setSubFileName(getModule(GroupModule.class).getSubName2())
//.setFileSize(32895492)
.start();
break;

@ -50,4 +50,78 @@ public class GroupModule extends BaseModule {
Collections.addAll(names, str);
return names;
}
List<String> getSubName2() {
List<String> taskSubFile;
taskSubFile = new ArrayList<>();
//taskSubFile.add("2156.mp4");
// taskSubFile.add("2115.mp4");
//taskSubFile.add("2009.mp4");
//taskSubFile.add("1893.mp4");
//taskSubFile.add("1952.mp4");
//taskSubFile.add("1958.mp4");
taskSubFile.add("1994.mp4");
//taskSubFile.add("2083.mp4");
taskSubFile.add("2305.JPG");
taskSubFile.add("2183.JPG");
taskSubFile.add("2154.JPG");
taskSubFile.add("2153.JPG");
taskSubFile.add("2152.JPG");
taskSubFile.add("2151.JPG");
taskSubFile.add("2149.JPG");
taskSubFile.add("2148.JPG");
taskSubFile.add("2147.JPG");
taskSubFile.add("2146.JPG");
taskSubFile.add("1949.JPG");
taskSubFile.add("1887.JPG");
taskSubFile.add("1996.txt");
return taskSubFile;
}
public List<String> getUrls2() {
List<String> downLoadUrls;
downLoadUrls = new ArrayList<>();
//downLoadUrls.add(
// "http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2156&clientId=A000011106034058176");
// downLoadUrls.add("http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2115&clientId=A000011106034058176");
//downLoadUrls.add(
// "http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2009&clientId=A000011106034058176");
//downLoadUrls.add(
// "http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=1893&clientId=A000011106034058176");
//downLoadUrls.add(
// "http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=1952&clientId=A000011106034058176");
//downLoadUrls.add(
// "http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=1958&clientId=A000011106034058176");
downLoadUrls.add(
"http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=1994&clientId=A000011106034058176");
//downLoadUrls.add(
// "http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2083&clientId=A000011106034058176");
downLoadUrls.add(
"http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2305&clientId=A000011106034058176");
downLoadUrls.add(
"http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2183&clientId=A000011106034058176");
downLoadUrls.add(
"http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2154&clientId=A000011106034058176");
downLoadUrls.add(
"http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2153&clientId=A000011106034058176");
downLoadUrls.add(
"http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2152&clientId=A000011106034058176");
downLoadUrls.add(
"http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2151&clientId=A000011106034058176");
downLoadUrls.add(
"http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2149&clientId=A000011106034058176");
downLoadUrls.add(
"http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2148&clientId=A000011106034058176");
downLoadUrls.add(
"http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2147&clientId=A000011106034058176");
downLoadUrls.add(
"http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2146&clientId=A000011106034058176");
downLoadUrls.add(
"http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=1949&clientId=A000011106034058176");
downLoadUrls.add(
"http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=1887&clientId=A000011106034058176");
downLoadUrls.add(
"http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=1996&clientId=A000011106034058176");
return downLoadUrls;
}
}

@ -27,7 +27,8 @@ public class AnyRunActivity extends BaseActivity<ActivityTestBinding> {
//String URL = "http://static.gaoshouyou.com/d/22/94/822260b849944492caadd2983f9bb624.apk";
//private final String URL = "ftp://192.168.29.140:21/download/AriaPrj.rar";
//String URL = "https://dl.genymotion.com/releases/genymotion-2.12.1/genymotion-2.12.1-vbox.exe";
String URL = "ftp://192.168.29.140:21/download/SDK_Demo-release.apk";
//String URL = "ftp://192.168.29.140:21/download/SDK_Demo-release.apk";
String URL = "http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=1994&clientId=A000011106034058176";
//String URL = "ftp://z:z@dygod18.com:21211/[电影天堂www.dy2018.com]猩球崛起3:终极之战BD国英双语中英双字.mkv";
//private String URL = "https://www.bilibili.com/bangumi/play/ep77693";
//private String URL = "http://cn-hbsjz-cmcc-v-03.acgvideo.com/upgcxcode/63/82/5108263/5108263-1-80.flv?expires=1530178500&platform=pc&ssig=vr7gLl0duyqWqSMnIpzaDA&oi=3746029570&nfa=BpfiWF+i4mNW8KzjZFHzBQ==&dynamic=1&hfa=2030547937&hfb=Yjk5ZmZjM2M1YzY4ZjAwYTMzMTIzYmIyNWY4ODJkNWI=&trid=3476be01a9254115b15f8cc7198600fe&nfc=1";
@ -49,8 +50,8 @@ public class AnyRunActivity extends BaseActivity<ActivityTestBinding> {
public void onClick(View view) {
switch (view.getId()) {
case R.id.start:
//module.start(URL);
module.startFtp(URL);
module.start(URL);
//module.startFtp(URL);
break;
case R.id.stop:
module.stop(URL);

@ -65,7 +65,7 @@ public class AnyRunnModule {
void start(String url) {
mUrl = url;
String path = Environment.getExternalStorageDirectory().getPath() + "/aaas.apk";
String path = Environment.getExternalStorageDirectory().getPath() + "/mmm.mp4";
Aria.download(this)
.load(url)
.setRequestMode(RequestEnum.GET)

Loading…
Cancel
Save