优化上传任务target的代码

v3.6.6
laoyuyu 6 years ago
parent 30c41e4cb2
commit b3501dc3c3
  1. 140
      Aria/src/main/java/com/arialyy/aria/core/common/ftp/FtpDelegate.java
  2. 33
      Aria/src/main/java/com/arialyy/aria/core/download/AbsDGTarget.java
  3. 68
      Aria/src/main/java/com/arialyy/aria/core/download/AbsDownloadTarget.java
  4. 199
      Aria/src/main/java/com/arialyy/aria/core/download/BaseNormalTarget.java
  5. 89
      Aria/src/main/java/com/arialyy/aria/core/download/DNormalDelegate.java
  6. 35
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTarget.java
  7. 20
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadTarget.java
  8. 9
      Aria/src/main/java/com/arialyy/aria/core/download/FtpDirDownloadTarget.java
  9. 12
      Aria/src/main/java/com/arialyy/aria/core/download/FtpDownloadTarget.java
  10. 20
      Aria/src/main/java/com/arialyy/aria/core/inf/AbsTarget.java
  11. 22
      Aria/src/main/java/com/arialyy/aria/core/upload/AbsUploadTarget.java
  12. 146
      Aria/src/main/java/com/arialyy/aria/core/upload/BaseNormalTarget.java
  13. 4
      Aria/src/main/java/com/arialyy/aria/core/upload/FtpUploadTarget.java
  14. 23
      Aria/src/main/java/com/arialyy/aria/core/upload/UNormalDelegate.java
  15. 2
      Aria/src/main/java/com/arialyy/aria/core/upload/UploadTarget.java
  16. 393
      Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpThreadTask.java
  17. 24
      Aria/src/main/java/com/arialyy/aria/exception/ParamException.java
  18. 578
      Aria/src/main/java/com/arialyy/aria/orm/DbEntity.java
  19. 490
      Aria/src/main/java/com/arialyy/aria/util/CheckUtil.java
  20. 2434
      Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java
  21. 4
      DEV_LOG.md
  22. 320
      app/src/main/assets/aria_config.xml
  23. 4
      app/src/main/java/com/arialyy/simple/core/download/FtpDownloadActivity.java
  24. 2
      app/src/main/java/com/arialyy/simple/core/download/HighestPriorityActivity.java
  25. 21
      app/src/main/java/com/arialyy/simple/core/download/SingleTaskActivity.java
  26. 160
      app/src/main/java/com/arialyy/simple/core/test/TestMutilTaskSysDownload.java
  27. 226
      app/src/main/java/com/arialyy/simple/core/upload/FtpUploadActivity.java

@ -1,70 +1,70 @@
/*
* 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.ftp;
import android.text.TextUtils;
import com.arialyy.aria.core.FtpUrlEntity;
import com.arialyy.aria.core.inf.AbsTarget;
import com.arialyy.aria.core.inf.IFtpTarget;
import com.arialyy.aria.util.ALog;
import java.net.Proxy;
/**
* Created by laoyuyu on 2018/3/9.
* ftp 委托
*/
public class FtpDelegate<TARGET extends AbsTarget> implements IFtpTarget<TARGET> {
private static final String TAG = "FtpDelegate";
private FtpUrlEntity mUrlEntity;
private TARGET mTarget;
public FtpDelegate(TARGET target) {
mTarget = target;
mUrlEntity = target.getTaskWrapper().asFtp().getUrlEntity();
}
@Override public TARGET charSet(String charSet) {
if (TextUtils.isEmpty(charSet)) {
throw new NullPointerException("字符编码为空");
}
mTarget.getTaskWrapper().asFtp().setCharSet(charSet);
return mTarget;
}
@Override public TARGET login(String userName, String password) {
return login(userName, password, null);
}
@Override public TARGET login(String userName, String password, String account) {
if (TextUtils.isEmpty(userName)) {
ALog.e(TAG, "用户名不能为null");
return mTarget;
} else if (TextUtils.isEmpty(password)) {
ALog.e(TAG, "密码不能为null");
return mTarget;
}
mUrlEntity.needLogin = true;
mUrlEntity.user = userName;
mUrlEntity.password = password;
mUrlEntity.account = account;
return mTarget;
}
@Override public TARGET setProxy(Proxy proxy) {
mTarget.getTaskWrapper().asFtp().setProxy(proxy);
return mTarget;
}
}
/*
* 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.ftp;
import android.text.TextUtils;
import com.arialyy.aria.core.FtpUrlEntity;
import com.arialyy.aria.core.inf.AbsTarget;
import com.arialyy.aria.core.inf.IFtpTarget;
import com.arialyy.aria.util.ALog;
import java.net.Proxy;
/**
* Created by laoyuyu on 2018/3/9.
* ftp 委托
*/
public class FtpDelegate<TARGET extends AbsTarget> implements IFtpTarget<TARGET> {
private static final String TAG = "FtpDelegate";
private TARGET mTarget;
public FtpDelegate(TARGET target) {
mTarget = target;
}
@Override public TARGET charSet(String charSet) {
if (TextUtils.isEmpty(charSet)) {
throw new NullPointerException("字符编码为空");
}
mTarget.getTaskWrapper().asFtp().setCharSet(charSet);
return mTarget;
}
@Override public TARGET login(String userName, String password) {
return login(userName, password, null);
}
@Override public TARGET login(String userName, String password, String account) {
if (TextUtils.isEmpty(userName)) {
ALog.e(TAG, "用户名不能为null");
return mTarget;
} else if (TextUtils.isEmpty(password)) {
ALog.e(TAG, "密码不能为null");
return mTarget;
}
// urlEntity 不能在构造函数中获取,因为ftp上传时url是后于构造函数的
FtpUrlEntity urlEntity = mTarget.getTaskWrapper().asFtp().getUrlEntity();
urlEntity.needLogin = true;
urlEntity.user = userName;
urlEntity.password = password;
urlEntity.account = account;
return mTarget;
}
@Override public TARGET setProxy(Proxy proxy) {
mTarget.getTaskWrapper().asFtp().setProxy(proxy);
return mTarget;
}
}

@ -19,6 +19,7 @@ import android.support.annotation.CheckResult;
import android.text.TextUtils;
import com.arialyy.aria.core.inf.AbsEntity;
import com.arialyy.aria.core.inf.AbsTarget;
import com.arialyy.aria.core.inf.AbsTaskWrapper;
import com.arialyy.aria.core.manager.SubTaskManager;
import com.arialyy.aria.core.queue.DownloadGroupTaskQueue;
import com.arialyy.aria.orm.DbEntity;
@ -30,8 +31,7 @@ import java.util.List;
/**
* Created by lyy on 2017/7/26.
*/
abstract class BaseGroupTarget<TARGET extends BaseGroupTarget>
extends AbsTarget<TARGET, DownloadGroupEntity, DGTaskWrapper> {
abstract class AbsDGTarget<TARGET extends AbsDGTarget> extends AbsTarget<TARGET> {
/**
* 组任务名
@ -61,13 +61,21 @@ abstract class BaseGroupTarget<TARGET extends BaseGroupTarget>
return mSubTaskManager;
}
@Override public DownloadGroupEntity getEntity() {
return (DownloadGroupEntity) super.getEntity();
}
@Override public DGTaskWrapper getTaskWrapper() {
return (DGTaskWrapper) super.getTaskWrapper();
}
/**
* 设置任务组别名
*/
@CheckResult
public TARGET setGroupAlias(String alias) {
if (TextUtils.isEmpty(alias)) return (TARGET) this;
mEntity.setAlias(alias);
getEntity().setAlias(alias);
return (TARGET) this;
}
@ -75,18 +83,6 @@ abstract class BaseGroupTarget<TARGET extends BaseGroupTarget>
return DbEntity.checkDataExist(DownloadGroupEntity.class, "groupHash=?", mGroupHash);
}
/**
* 设置任务组的文件夹路径该api后续会删除
*
* @param groupDirPath 任务组保存文件夹路径
* @deprecated {@link #setDirPath(String)} 请使用这个api
*/
@Deprecated
@CheckResult
public TARGET setDownloadDirPath(String groupDirPath) {
return setDirPath(groupDirPath);
}
/**
* 设置任务组的文件夹路径在Aria中任务组的所有子任务都会下载到以任务组组名的文件夹中
* groupDirPath = "/mnt/sdcard/download/group_test"
@ -113,7 +109,7 @@ abstract class BaseGroupTarget<TARGET extends BaseGroupTarget>
}
@Override public boolean isRunning() {
DownloadGroupTask task = DownloadGroupTaskQueue.getInstance().getTask(mEntity.getKey());
DownloadGroupTask task = DownloadGroupTaskQueue.getInstance().getTask(getEntity().getKey());
return task != null && task.isRunning();
}
@ -160,12 +156,13 @@ abstract class BaseGroupTarget<TARGET extends BaseGroupTarget>
return false;
}
if (TextUtils.isEmpty(mEntity.getDirPath()) || !mEntity.getDirPath().equals(mDirPathTemp)) {
if (TextUtils.isEmpty(getEntity().getDirPath()) || !getEntity().getDirPath()
.equals(mDirPathTemp)) {
if (!file.exists()) {
file.mkdirs();
}
needModifyPath = true;
mEntity.setDirPath(mDirPathTemp);
getEntity().setDirPath(mDirPathTemp);
ALog.i(TAG, String.format("文件夹路径改变,将更新文件夹路径为:%s", mDirPathTemp));
}

@ -23,22 +23,7 @@ import com.arialyy.aria.util.CommonUtil;
/**
* Created by lyy on 2017/2/28.
*/
abstract class AbsDownloadTarget<TARGET extends AbsDownloadTarget>
extends AbsTarget<TARGET, DownloadEntity, DTaskWrapper> {
/**
* 设置的文件保存路径的临时变量
*/
private String mTempFilePath;
/**
* {@code true}强制下载不考虑文件路径是否被占用
*/
private boolean forceDownload = false;
/**
* 资源地址
*/
private String mUrl, mNewUrl;
abstract class AbsDownloadTarget<TARGET extends AbsDownloadTarget> extends AbsTarget<TARGET> {
/**
* 更新下载url
@ -66,56 +51,7 @@ abstract class AbsDownloadTarget<TARGET extends AbsDownloadTarget>
}
}
/**
* 是否强制下载文件 {@link DownloadTarget#setFilePath(String, boolean)}
* {@link FtpDownloadTarget#setFilePath(String, boolean)}
*
* @return {@code true} 强制下载文件
*/
boolean isForceDownload() {
return forceDownload;
}
@Override public void setTaskWrapper(DTaskWrapper taskWrapper) {
super.setTaskWrapper(taskWrapper);
}
/**
* 文件保存路径的临时变量
*/
String getTempFilePath() {
return mTempFilePath;
}
void setForceDownload(boolean forceDownload) {
this.forceDownload = forceDownload;
}
public String getUrl() {
return mUrl;
}
void setUrl(String url) {
this.mUrl = url;
}
String getNewUrl() {
return mNewUrl;
}
void setNewUrl(String newUrl) {
this.mNewUrl = newUrl;
}
void setTempFilePath(String mTempFilePath) {
this.mTempFilePath = mTempFilePath;
}
public void setEntity(DownloadEntity entity) {
mEntity = entity;
}
@Override public DownloadEntity getEntity() {
return super.getEntity();
return (DownloadEntity) super.getEntity();
}
}

@ -1,199 +0,0 @@
///*
// * 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.download;
//
//import android.text.TextUtils;
//import com.arialyy.aria.core.manager.TaskWrapperManager;
//import com.arialyy.aria.core.queue.DownloadTaskQueue;
//import com.arialyy.aria.orm.DbEntity;
//import com.arialyy.aria.util.ALog;
//import com.arialyy.aria.util.CommonUtil;
//import java.io.File;
//
///**
// * Created by Aria.Lao on 2017/7/26.
// */
//abstract class BaseNormalTarget<TARGET extends BaseNormalTarget>
// extends AbsDownloadTarget<TARGET, DownloadEntity, DTaskWrapper> {
//
// /**
// * 通过地址初始化target
// */
// void initTarget(String url, String targetName) {
// setUrl(url);
// setTargetName(targetName);
// setTaskWrapper(TaskWrapperManager.getInstance().getHttpTaskWrapper(DTaskWrapper.class, url));
// mEntity = getTaskWrapper().getEntity();
//
// if (mEntity != null) {
// setTempFilePath(mEntity.getDownloadPath());
// }
// }
//
// /**
// * 更新下载url
// *
// * @param newUrl 新的下载url
// */
// public TARGET updateUrl(String newUrl) {
// if (TextUtils.isEmpty(newUrl)) {
// ALog.e(TAG, "下载url更新失败,newUrl为null");
// return (TARGET) this;
// }
// if (getUrl().equals(newUrl)) {
// ALog.e(TAG, "下载url更新失败,新的下载url和旧的url一致");
// return (TARGET) this;
// }
// setNewUrl(newUrl);
// getTaskWrapper().setRefreshInfo(true);
// return (TARGET) this;
// }
//
// /**
// * 将任务设置为最高优先级任务,最高优先级任务有以下特点:
// * 1、在下载队列中,有且只有一个最高优先级任务
// * 2、最高优先级任务会一直存在,直到用户手动暂停或任务完成
// * 3、任务调度器不会暂停最高优先级任务
// * 4、用户手动暂停或任务完成后,第二次重新执行该任务,该命令将失效
// * 5、如果下载队列中已经满了,则会停止队尾的任务,当高优先级任务完成后,该队尾任务将自动执行
// * 6、把任务设置为最高优先级任务后,将自动执行任务,不需要重新调用start()启动任务
// */
// @Override public void setHighestPriority() {
// super.setHighestPriority();
// }
//
// /**
// * 下载任务是否存在
// *
// * @return {@code true}任务存在
// */
// @Override public boolean taskExists() {
// return DbEntity.checkDataExist(DownloadEntity.class, "url=?", getUrl());
// }
//
// /**
// * 获取下载实体
// */
// public DownloadEntity getDownloadEntity() {
// return mEntity;
// }
//
// /**
// * 是否在下载
// *
// * @return {@code true}任务正在下载
// */
// @Override public boolean isRunning() {
// DownloadTask task = DownloadTaskQueue.getInstance().getTask(mEntity.getKey());
// return task != null && task.isRunning();
// }
//
// /**
// * 检查下载实体,判断实体是否合法 合法标准为:
// * 1、下载路径不为null,并且下载路径是正常的http或ftp路径
// * 2、保存路径不为null,并且保存路径是android文件系统路径
// * 3、保存路径不能重复
// *
// * @return {@code true}合法
// */
// @Override protected boolean checkEntity() {
// boolean b = getTargetType() < GROUP_HTTP && checkUrl() && checkFilePath();
// if (b) {
// mEntity.save();
// }
// return b;
// }
//
// /**
// * 检查并设置普通任务的文件保存路径
// *
// * @return {@code true}保存路径合法
// */
// private boolean checkFilePath() {
// String filePath = getTempFilePath();
// if (TextUtils.isEmpty(filePath)) {
// ALog.e(TAG, "下载失败,文件保存路径为null");
// return false;
// } else if (!filePath.startsWith("/")) {
// ALog.e(TAG, "下载失败,文件保存路径【" + filePath + "】错误");
// return false;
// }
// File file = new File(filePath);
// if (file.isDirectory()) {
// if (getTargetType() == HTTP) {
// ALog.e(TAG, "下载失败,保存路径【" + filePath + "】不能为文件夹,路径需要是完整的文件路径,如:/mnt/sdcard/game.zip");
// return false;
// } else if (getTargetType() == FTP) {
// filePath += mEntity.getFileName();
// }
// } else {
// // http文件名设置
// if (TextUtils.isEmpty(mEntity.getFileName())) {
// mEntity.setFileName(file.getName());
// }
// }
//
// //设置文件保存路径,如果新文件路径和旧文件路径不同,则修改路径
// if (!filePath.equals(mEntity.getDownloadPath())) {
// // 检查路径冲突
// if (DbEntity.checkDataExist(DownloadEntity.class, "downloadPath=?", filePath)) {
// if (!isForceDownload()) {
// ALog.e(TAG, "下载失败,保存路径【" + filePath + "】已经被其它任务占用,请设置其它保存路径");
// return false;
// } else {
// ALog.w(TAG, "保存路径【" + filePath + "】已经被其它任务占用,当前任务将覆盖该路径的文件");
// CommonUtil.delTaskRecord(filePath, 1);
// setTaskWrapper(
// TaskWrapperManager.getInstance().getHttpTaskWrapper(DTaskWrapper.class, getUrl()));
// }
// }
// File oldFile = new File(mEntity.getDownloadPath());
// File newFile = new File(filePath);
// mEntity.setDownloadPath(filePath);
// mEntity.setFileName(newFile.getName());
// if (oldFile.exists()) {
// oldFile.renameTo(newFile);
// CommonUtil.modifyTaskRecord(oldFile.getPath(), newFile.getPath());
// }
// }
// return true;
// }
//
// /**
// * 检查普通任务的下载地址
// *
// * @return {@code true}地址合法
// */
// private boolean checkUrl() {
// final String url = mEntity.getUrl();
// if (TextUtils.isEmpty(url)) {
// ALog.e(TAG, "下载失败,url为null");
// return false;
// } else if (!url.startsWith("http") && !url.startsWith("ftp")) {
// ALog.e(TAG, "下载失败,url【" + url + "】错误");
// return false;
// }
// int index = url.indexOf("://");
// if (index == -1) {
// ALog.e(TAG, "下载失败,url【" + url + "】不合法");
// return false;
// }
// if (!TextUtils.isEmpty(getNewUrl())) {
// mEntity.setUrl(getNewUrl());
// }
// return true;
// }
//}

@ -33,46 +33,60 @@ class DNormalDelegate<TARGET extends AbsDownloadTarget> implements ITargetNormal
private final String TAG = "DNormalDelegate";
private DownloadEntity mEntity;
private TARGET target;
private TARGET mTarget;
private String mNewUrl;
/**
* 设置的文件保存路径的临时变量
*/
private String mTempFilePath;
/**
* {@code true}强制下载不考虑文件路径是否被占用
*/
private boolean forceDownload = false;
/**
* 资源地址
*/
private String mUrl;
DNormalDelegate(TARGET target, String url, String targetName) {
this.target = target;
this.mTarget = target;
initTarget(url, targetName);
}
@Override public void initTarget(String url, String targetName) {
DTaskWrapper taskWrapper = TaskWrapperManager.getInstance().getHttpTaskWrapper(DTaskWrapper.class, url);
DTaskWrapper taskWrapper =
TaskWrapperManager.getInstance().getHttpTaskWrapper(DTaskWrapper.class, url);
mEntity = taskWrapper.getEntity();
target.setUrl(url);
target.setTargetName(targetName);
target.setTaskWrapper(taskWrapper);
target.setEntity(mEntity);
mUrl = url;
mTarget.setTargetName(targetName);
mTarget.setTaskWrapper(taskWrapper);
if (mEntity != null) {
target.setTempFilePath(mEntity.getDownloadPath());
mTempFilePath = mEntity.getDownloadPath();
}
}
@Override public TARGET updateUrl(String newUrl) {
if (TextUtils.isEmpty(newUrl)) {
ALog.e(TAG, "下载url更新失败,newUrl为null");
return target;
ALog.e(TAG, "url更新失败,newUrl为null");
return mTarget;
}
if (target.getUrl().equals(newUrl)) {
ALog.e(TAG, "下载url更新失败,新的下载url和旧的url一致");
return target;
if (mUrl.equals(newUrl)) {
ALog.e(TAG, "url更新失败,新的下载url和旧的url一致");
return mTarget;
}
target.setNewUrl(newUrl);
target.getTaskWrapper().setRefreshInfo(true);
return target;
mNewUrl = newUrl;
mTarget.getTaskWrapper().setRefreshInfo(true);
return mTarget;
}
@Override public DownloadEntity getEntity() {
return target.getEntity();
return mTarget.getEntity();
}
@Override public boolean taskExists() {
return DbEntity.checkDataExist(DownloadEntity.class, "url=?", target.getUrl());
return DbEntity.checkDataExist(DownloadEntity.class, "url=?", mUrl);
}
@Override public boolean isRunning() {
@ -89,7 +103,7 @@ class DNormalDelegate<TARGET extends AbsDownloadTarget> implements ITargetNormal
}
@Override public boolean checkFilePath() {
String filePath = target.getTempFilePath();
String filePath = mTempFilePath;
if (TextUtils.isEmpty(filePath)) {
ALog.e(TAG, "下载失败,文件保存路径为null");
return false;
@ -99,10 +113,10 @@ class DNormalDelegate<TARGET extends AbsDownloadTarget> implements ITargetNormal
}
File file = new File(filePath);
if (file.isDirectory()) {
if (target.getTargetType() == ITargetHandler.HTTP) {
if (mTarget.getTargetType() == ITargetHandler.HTTP) {
ALog.e(TAG, "下载失败,保存路径【" + filePath + "】不能为文件夹,路径需要是完整的文件路径,如:/mnt/sdcard/game.zip");
return false;
} else if (target.getTargetType() == ITargetHandler.FTP) {
} else if (mTarget.getTargetType() == ITargetHandler.FTP) {
filePath += mEntity.getFileName();
}
} else {
@ -116,15 +130,15 @@ class DNormalDelegate<TARGET extends AbsDownloadTarget> implements ITargetNormal
if (!filePath.equals(mEntity.getDownloadPath())) {
// 检查路径冲突
if (DbEntity.checkDataExist(DownloadEntity.class, "downloadPath=?", filePath)) {
if (!target.isForceDownload()) {
if (!forceDownload) {
ALog.e(TAG, "下载失败,保存路径【" + filePath + "】已经被其它任务占用,请设置其它保存路径");
return false;
} else {
ALog.w(TAG, "保存路径【" + filePath + "】已经被其它任务占用,当前任务将覆盖该路径的文件");
CommonUtil.delTaskRecord(filePath, 1);
target.setTaskWrapper(
mTarget.setTaskWrapper(
TaskWrapperManager.getInstance()
.getHttpTaskWrapper(DTaskWrapper.class, target.getUrl()));
.getHttpTaskWrapper(DTaskWrapper.class, mUrl));
}
}
File oldFile = new File(mEntity.getDownloadPath());
@ -132,8 +146,13 @@ class DNormalDelegate<TARGET extends AbsDownloadTarget> implements ITargetNormal
mEntity.setDownloadPath(filePath);
mEntity.setFileName(newFile.getName());
if (oldFile.exists()) {
oldFile.renameTo(newFile);
// 处理普通任务的重命名
CommonUtil.modifyTaskRecord(oldFile.getPath(), newFile.getPath());
ALog.i(TAG, String.format("将任务重命名为:%s", newFile.getName()));
} else if (CommonUtil.blockTaskExists(oldFile.getPath())) {
// 处理分块任务的重命名
CommonUtil.modifyTaskRecord(oldFile.getPath(), newFile.getPath());
ALog.i(TAG, String.format("将分块任务重命名为:%s", newFile.getName()));
}
}
return true;
@ -153,9 +172,25 @@ class DNormalDelegate<TARGET extends AbsDownloadTarget> implements ITargetNormal
ALog.e(TAG, "下载失败,url【" + url + "】不合法");
return false;
}
if (!TextUtils.isEmpty(target.getNewUrl())) {
mEntity.setUrl(target.getNewUrl());
if (!TextUtils.isEmpty(mNewUrl)) {
mEntity.setUrl(mNewUrl);
}
return true;
}
void setForceDownload(boolean forceDownload) {
this.forceDownload = forceDownload;
}
void setUrl(String url) {
this.mUrl = url;
}
String getUrl() {
return mUrl;
}
void setTempFilePath(String mTempFilePath) {
this.mTempFilePath = mTempFilePath;
}
}

@ -26,7 +26,6 @@ import com.arialyy.aria.core.manager.TaskWrapperManager;
import com.arialyy.aria.orm.DbEntity;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil;
import java.io.File;
import java.net.Proxy;
import java.util.ArrayList;
import java.util.HashSet;
@ -38,7 +37,7 @@ import java.util.Set;
* Created by AriaL on 2017/6/29.
* 下载任务组
*/
public class DownloadGroupTarget extends BaseGroupTarget<DownloadGroupTarget> implements
public class DownloadGroupTarget extends AbsDGTarget<DownloadGroupTarget> implements
IHttpHeaderDelegate<DownloadGroupTarget> {
private HttpHeaderDelegate<DownloadGroupTarget> mDelegate;
/**
@ -68,9 +67,8 @@ public class DownloadGroupTarget extends BaseGroupTarget<DownloadGroupTarget> im
private void init() {
mGroupHash = CommonUtil.getMd5Code(mUrls);
setTaskWrapper(TaskWrapperManager.getInstance().getDGTaskWrapper(DGTaskWrapper.class, mUrls));
mEntity = getEntity();
if (mEntity != null) {
mDirPathTemp = mEntity.getDirPath();
if (getEntity() != null) {
mDirPathTemp = getEntity().getDirPath();
}
mDelegate = new HttpHeaderDelegate<>(this);
}
@ -98,10 +96,10 @@ public class DownloadGroupTarget extends BaseGroupTarget<DownloadGroupTarget> im
mUrls.clear();
mUrls.addAll(urls);
mGroupHash = CommonUtil.getMd5Code(urls);
mEntity.setGroupHash(mGroupHash);
mEntity.update();
if (mEntity.getSubEntities() != null && !mEntity.getSubEntities().isEmpty()) {
for (DownloadEntity de : mEntity.getSubEntities()) {
getEntity().setGroupHash(mGroupHash);
getEntity().update();
if (getEntity().getSubEntities() != null && !getEntity().getSubEntities().isEmpty()) {
for (DownloadEntity de : getEntity().getSubEntities()) {
de.setGroupHash(mGroupHash);
de.update();
}
@ -123,8 +121,8 @@ public class DownloadGroupTarget extends BaseGroupTarget<DownloadGroupTarget> im
ALog.e(TAG, "文件大小不能小于 0");
return this;
}
if (mEntity.getFileSize() <= 1 || mEntity.getFileSize() != fileSize) {
mEntity.setFileSize(fileSize);
if (getEntity().getFileSize() <= 1 || getEntity().getFileSize() != fileSize) {
getEntity().setFileSize(fileSize);
}
return this;
}
@ -196,7 +194,7 @@ public class DownloadGroupTarget extends BaseGroupTarget<DownloadGroupTarget> im
}
}
mEntity.save();
getEntity().save();
if (needModifyPath) {
reChangeDirPath(mDirPathTemp);
@ -266,7 +264,7 @@ public class DownloadGroupTarget extends BaseGroupTarget<DownloadGroupTarget> im
}
}
mEntity.setGroupHash(CommonUtil.getMd5Code(mUrls));
getEntity().setGroupHash(CommonUtil.getMd5Code(mUrls));
return true;
}
@ -277,20 +275,15 @@ public class DownloadGroupTarget extends BaseGroupTarget<DownloadGroupTarget> im
private void updateSingleSubFileName(DTaskWrapper taskEntity, String newName) {
DownloadEntity entity = taskEntity.getEntity();
if (!newName.equals(entity.getFileName())) {
String oldPath = mEntity.getDirPath() + "/" + entity.getFileName();
String newPath = mEntity.getDirPath() + "/" + newName;
String oldPath = getEntity().getDirPath() + "/" + entity.getFileName();
String newPath = getEntity().getDirPath() + "/" + newName;
if (DbEntity.checkDataExist(DownloadEntity.class, "downloadPath=? or isComplete='true'",
newPath)) {
ALog.w(TAG, String.format("更新文件名失败,路径【%s】已存在或文件已下载", newPath));
return;
}
File oldFile = new File(oldPath);
if (oldFile.exists()) {
oldFile.renameTo(new File(newPath));
}
CommonUtil.modifyTaskRecord(oldFile.getPath(), newPath);
CommonUtil.modifyTaskRecord(oldPath, newPath);
entity.setDownloadPath(newPath);
entity.setFileName(newName);
entity.update();

@ -70,18 +70,6 @@ public class DownloadTarget extends AbsDownloadTarget<DownloadTarget>
return this;
}
/**
* 设置文件存储路径
* 该api后续版本会删除
*
* @param downloadPath 文件保存路径
* @deprecated {@link #setFilePath(String)} 请使用这个api
*/
@CheckResult
@Deprecated public DownloadTarget setDownloadPath(@NonNull String downloadPath) {
return setFilePath(downloadPath);
}
/**
* 设置文件存储路径如果需要修改新的文件名修改路径便可
* 原文件路径 /mnt/sdcard/test.zip
@ -91,7 +79,7 @@ public class DownloadTarget extends AbsDownloadTarget<DownloadTarget>
*/
@CheckResult
public DownloadTarget setFilePath(@NonNull String filePath) {
setTempFilePath(filePath);
mNormalDelegate.setTempFilePath(filePath);
return this;
}
@ -105,8 +93,8 @@ public class DownloadTarget extends AbsDownloadTarget<DownloadTarget>
*/
@CheckResult
public DownloadTarget setFilePath(@NonNull String filePath, boolean forceDownload) {
setTempFilePath(filePath);
setForceDownload(forceDownload);
mNormalDelegate.setTempFilePath(filePath);
mNormalDelegate.setForceDownload(forceDownload);
return this;
}
@ -114,7 +102,7 @@ public class DownloadTarget extends AbsDownloadTarget<DownloadTarget>
* 从header中获取文件描述信息
*/
public String getContentDisposition() {
return mEntity.getDisposition();
return getEntity().getDisposition();
}
@Override public DownloadTarget updateUrl(String newUrl) {

@ -30,7 +30,7 @@ import java.net.Proxy;
* Created by Aria.Lao on 2017/7/26.
* ftp文件夹下载
*/
public class FtpDirDownloadTarget extends BaseGroupTarget<FtpDirDownloadTarget>
public class FtpDirDownloadTarget extends AbsDGTarget<FtpDirDownloadTarget>
implements IFtpTarget<FtpDirDownloadTarget> {
private FtpDelegate<FtpDirDownloadTarget> mDelegate;
@ -43,9 +43,8 @@ public class FtpDirDownloadTarget extends BaseGroupTarget<FtpDirDownloadTarget>
mGroupHash = key;
setTaskWrapper(TaskWrapperManager.getInstance().getFtpTaskWrapper(DGTaskWrapper.class, key));
getTaskWrapper().setRequestType(AbsTaskWrapper.D_FTP_DIR);
mEntity = getEntity();
if (mEntity != null) {
mDirPathTemp = mEntity.getDirPath();
if (getEntity() != null) {
mDirPathTemp = getEntity().getDirPath();
}
mDelegate = new FtpDelegate<>(this);
}
@ -57,7 +56,7 @@ public class FtpDirDownloadTarget extends BaseGroupTarget<FtpDirDownloadTarget>
@Override protected boolean checkEntity() {
boolean b = getTargetType() == GROUP_FTP_DIR && checkDirPath() && checkUrl();
if (b) {
mEntity.save();
getEntity().save();
if (getTaskWrapper().getSubTaskWrapper() != null) {
//初始化子项的登录信息
FtpUrlEntity tUrlEntity = getTaskWrapper().asFtp().getUrlEntity();

@ -45,9 +45,9 @@ public class FtpDownloadTarget extends AbsDownloadTarget<FtpDownloadTarget>
}
private void init() {
int lastIndex = getUrl().lastIndexOf("/");
mEntity.setFileName(getUrl().substring(lastIndex + 1));
getTaskWrapper().asFtp().setUrlEntity(CommonUtil.getFtpUrlInfo(getUrl()));
int lastIndex = mNormalDelegate.getUrl().lastIndexOf("/");
getEntity().setFileName(mNormalDelegate.getUrl().substring(lastIndex + 1));
getTaskWrapper().asFtp().setUrlEntity(CommonUtil.getFtpUrlInfo(mNormalDelegate.getUrl()));
getTaskWrapper().setRequestType(AbsTaskWrapper.D_FTP);
mFtpDelegate = new FtpDelegate<>(this);
@ -106,7 +106,7 @@ public class FtpDownloadTarget extends AbsDownloadTarget<FtpDownloadTarget>
*/
@CheckResult
public FtpDownloadTarget setFilePath(@NonNull String filePath) {
setTempFilePath(filePath);
mNormalDelegate.setTempFilePath(filePath);
return this;
}
@ -120,8 +120,8 @@ public class FtpDownloadTarget extends AbsDownloadTarget<FtpDownloadTarget>
*/
@CheckResult
public FtpDownloadTarget setFilePath(@NonNull String filePath, boolean forceDownload) {
setTempFilePath(filePath);
setForceDownload(forceDownload);
mNormalDelegate.setTempFilePath(filePath);
mNormalDelegate.setForceDownload(forceDownload);
return this;
}

@ -36,18 +36,22 @@ import java.util.List;
/**
* Created by AriaL on 2017/7/3.
*/
public abstract class AbsTarget<TARGET extends AbsTarget, ENTITY extends AbsEntity, TASK_WRAPPER extends AbsTaskWrapper>
implements ITargetHandler {
public abstract class AbsTarget<TARGET extends AbsTarget> implements ITargetHandler {
protected String TAG;
protected ENTITY mEntity;
private TASK_WRAPPER mTaskWrapper;
private AbsEntity mEntity;
private AbsTaskWrapper mTaskWrapper;
private String mTargetName;
protected AbsTarget() {
TAG = CommonUtil.getClassName(this);
}
public void setTaskWrapper(AbsTaskWrapper wrapper) {
mTaskWrapper = wrapper;
mEntity = wrapper.getEntity();
}
/**
* 重置状态将任务状态设置为未开始状态
* 注意如果在后续方法调用链中没有调用 {@link #start()}{@link #stop()}{@link #cancel()}{@link #resume()}
@ -83,14 +87,10 @@ public abstract class AbsTarget<TARGET extends AbsTarget, ENTITY extends AbsEnti
}
}
public ENTITY getEntity() {
public AbsEntity getEntity() {
return mEntity;
}
public void setTaskWrapper(TASK_WRAPPER mTaskWrapper) {
this.mTaskWrapper = mTaskWrapper;
}
public String getTargetName() {
return mTargetName;
}
@ -102,7 +102,7 @@ public abstract class AbsTarget<TARGET extends AbsTarget, ENTITY extends AbsEnti
/**
* 获取任务实体
*/
public TASK_WRAPPER getTaskWrapper() {
public AbsTaskWrapper getTaskWrapper() {
return mTaskWrapper;
}

@ -21,27 +21,7 @@ import com.arialyy.aria.core.inf.AbsTarget;
* Created by AriaL on 2017/6/29.
* 普通上传任务接收器
*/
abstract class AbsUploadTarget<TARGET extends AbsUploadTarget>
extends AbsTarget<TARGET, UploadEntity, UTaskWrapper> {
abstract class AbsUploadTarget<TARGET extends AbsUploadTarget> extends AbsTarget<TARGET> {
/**
* 上传路径
*/
private String mTempUrl;
@Override public void setTaskWrapper(UTaskWrapper mTaskWrapper) {
super.setTaskWrapper(mTaskWrapper);
}
String getTempUrl() {
return mTempUrl;
}
void setTempUrl(String tempUrl) {
this.mTempUrl = tempUrl;
}
void setEntity(UploadEntity entity) {
this.mEntity = entity;
}
}

@ -1,146 +0,0 @@
///*
// * 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.upload;
//
//import android.support.annotation.CheckResult;
//import android.support.annotation.NonNull;
//import android.text.TextUtils;
//import com.arialyy.aria.core.manager.TaskWrapperManager;
//import com.arialyy.aria.core.queue.UploadTaskQueue;
//import com.arialyy.aria.orm.DbEntity;
//import com.arialyy.aria.util.ALog;
//import java.io.File;
//
///**
// * Created by AriaL on 2018/3/9.
// */
//abstract class BaseNormalTarget<TARGET extends AbsUploadTarget>
// extends AbsUploadTarget<TARGET, UploadEntity, UTaskWrapper> {
//
// protected String mTempUrl;
//
// void initTarget(String filePath) {
// mTaskWrapper =
// TaskWrapperManager.getInstance().getHttpTaskWrapper(UTaskWrapper.class, filePath);
// mEntity = mTaskWrapper.getEntity();
// File file = new File(filePath);
// mEntity.setFileName(file.getName());
// mEntity.setFileSize(file.length());
// mTempUrl = mEntity.getUrl();
// }
//
// /**
// * 设置上传路径
// *
// * @param uploadUrl 上传路径
// */
// @CheckResult
// public TARGET setTempUrl(@NonNull String uploadUrl) {
// mTempUrl = uploadUrl;
// return (TARGET) this;
// }
//
// /**
// * 上传任务是否存在
// *
// * @return {@code true}存在
// */
// @Override public boolean taskExists() {
// return DbEntity.checkDataExist(UploadEntity.class, "key=?", mEntity.getFilePath());
// }
//
// /**
// * 是否在上传
// *
// * @deprecated {@link #isRunning()}
// */
// public boolean isUploading() {
// return isRunning();
// }
//
// @Override public boolean isRunning() {
// UploadTask task = UploadTaskQueue.getInstance().getTask(mEntity.getKey());
// return task != null && task.isRunning();
// }
//
// @Override protected boolean checkEntity() {
// boolean b = checkUrl() && checkFilePath();
// if (b) {
// mEntity.save();
// }
// if (mTaskWrapper.asFtp().getUrlEntity() != null && mTaskWrapper.asFtp().getUrlEntity().isFtps) {
// //if (TextUtils.isEmpty(mTaskWrapper.getUrlEntity().storePath)) {
// // ALog.e(TAG, "证书路径为空");
// // return false;
// //}
// if (TextUtils.isEmpty(mTaskWrapper.asFtp().getUrlEntity().keyAlias)) {
// ALog.e(TAG, "证书别名为空");
// return false;
// }
// }
// return b;
// }
//
// /**
// * 检查上传文件路径是否合法
// *
// * @return {@code true} 合法
// */
// private boolean checkFilePath() {
// String filePath = mEntity.getFilePath();
// if (TextUtils.isEmpty(filePath)) {
// ALog.e(TAG, "上传失败,文件路径为null");
// return false;
// } else if (!filePath.startsWith("/")) {
// ALog.e(TAG, "上传失败,文件路径【" + filePath + "】不合法");
// return false;
// }
//
// File file = new File(mEntity.getFilePath());
// if (!file.exists()) {
// ALog.e(TAG, "上传失败,文件【" + filePath + "】不存在");
// return false;
// }
// if (file.isDirectory()) {
// ALog.e(TAG, "上传失败,文件【" + filePath + "】不能是文件夹");
// return false;
// }
// return true;
// }
//
// /**
// * 检查普通任务的下载地址
// *
// * @return {@code true}地址合法
// */
// protected boolean checkUrl() {
// final String url = mTempUrl;
// if (TextUtils.isEmpty(url)) {
// ALog.e(TAG, "上传失败,url为null");
// return false;
// } else if (!url.startsWith("http") && !url.startsWith("ftp")) {
// ALog.e(TAG, "上传失败,url【" + url + "】错误");
// return false;
// }
// int index = url.indexOf("://");
// if (index == -1) {
// ALog.e(TAG, "上传失败,url【" + url + "】不合法");
// return false;
// }
// mEntity.setUrl(url);
// return true;
// }
//}

@ -21,6 +21,7 @@ import com.arialyy.aria.core.common.ftp.FTPSDelegate;
import com.arialyy.aria.core.common.ftp.FtpDelegate;
import com.arialyy.aria.core.inf.AbsTaskWrapper;
import com.arialyy.aria.core.inf.IFtpTarget;
import com.arialyy.aria.util.CheckUtil;
import java.net.Proxy;
/**
@ -48,7 +49,7 @@ public class FtpUploadTarget extends AbsUploadTarget<FtpUploadTarget>
* @param tempUrl 上传路径
*/
public FtpUploadTarget setUploadUrl(String tempUrl) {
setTempUrl(tempUrl);
mNormalDelegate.setTempUrl(tempUrl);
return this;
}
@ -77,6 +78,7 @@ public class FtpUploadTarget extends AbsUploadTarget<FtpUploadTarget>
}
@Override public FtpUploadTarget login(String userName, String password, String account) {
CheckUtil.checkFtpUploadUrl(mNormalDelegate.getTempUrl());
return mFtpDelegate.login(userName, password, account);
}

@ -22,16 +22,21 @@ import com.arialyy.aria.core.manager.TaskWrapperManager;
import com.arialyy.aria.core.queue.UploadTaskQueue;
import com.arialyy.aria.orm.DbEntity;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil;
import java.io.File;
/**
* Created by Aria.Lao on 2019/4/5.
* 普通上传任务通用功能处理
*/
public class UNormalDelegate<TARGET extends AbsUploadTarget> implements ITargetNormal<TARGET> {
class UNormalDelegate<TARGET extends AbsUploadTarget> implements ITargetNormal<TARGET> {
private String TAG = "UNormalDelegate";
private UploadEntity mEntity;
private TARGET mTarget;
/**
* 上传路径
*/
private String mTempUrl;
UNormalDelegate(TARGET target, String filePath, String targetName) {
mTarget = target;
@ -47,12 +52,11 @@ public class UNormalDelegate<TARGET extends AbsUploadTarget> implements ITargetN
mEntity.setFileSize(file.length());
mTarget.setTargetName(targetName);
mTarget.setTaskWrapper(taskWrapper);
mTarget.setEntity(mEntity);
mTarget.setTempUrl(mEntity.getUrl());
mTempUrl = mEntity.getUrl();
}
@Override public TARGET updateUrl(String newUrl) {
mTarget.setTempUrl(mEntity.getUrl());
mTempUrl = newUrl;
return mTarget;
}
@ -113,7 +117,7 @@ public class UNormalDelegate<TARGET extends AbsUploadTarget> implements ITargetN
@Override public boolean checkUrl() {
final String url = mTarget.getTempUrl();
final String url = mTempUrl;
if (TextUtils.isEmpty(url)) {
ALog.e(TAG, "上传失败,url为null");
return false;
@ -129,4 +133,13 @@ public class UNormalDelegate<TARGET extends AbsUploadTarget> implements ITargetN
mEntity.setUrl(url);
return true;
}
void setTempUrl(String tempUrl) {
this.mTempUrl = tempUrl;
mTarget.getTaskWrapper().asFtp().setUrlEntity(CommonUtil.getFtpUrlInfo(tempUrl));
}
public String getTempUrl() {
return mTempUrl;
}
}

@ -51,7 +51,7 @@ public class UploadTarget extends AbsUploadTarget<UploadTarget>
* @param tempUrl 上传路径
*/
public UploadTarget setUploadUrl(String tempUrl) {
setTempUrl(tempUrl);
mNormalDelegate.setTempUrl(tempUrl);
return this;
}

@ -1,199 +1,194 @@
/*
* 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.upload.uploader;
import aria.apache.commons.net.ftp.FTPClient;
import aria.apache.commons.net.ftp.FTPReply;
import aria.apache.commons.net.ftp.OnFtpInputStreamListener;
import com.arialyy.aria.core.common.StateConstance;
import com.arialyy.aria.core.common.SubThreadConfig;
import com.arialyy.aria.core.common.ftp.AbsFtpThreadTask;
import com.arialyy.aria.core.config.BaseTaskConfig;
import com.arialyy.aria.core.config.DownloadConfig;
import com.arialyy.aria.core.config.UploadConfig;
import com.arialyy.aria.core.inf.IEventListener;
import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.core.upload.UTaskWrapper;
import com.arialyy.aria.exception.AriaIOException;
import com.arialyy.aria.exception.TaskException;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.BufferedRandomAccessFile;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
/**
* Created by Aria.Lao on 2017/7/28. FTP 单线程上传任务需要FTP 服务器给用户打开append和write的权限
*/
class FtpThreadTask extends AbsFtpThreadTask<UploadEntity, UTaskWrapper> {
private final String TAG = "FtpThreadTask";
private String dir, remotePath;
FtpThreadTask(StateConstance constance, IEventListener listener,
SubThreadConfig<UTaskWrapper> info) {
super(constance, listener, info);
}
@Override public int getMaxSpeed() {
return getTaskConfig().getMaxSpeed();
}
@Override protected UploadConfig getTaskConfig() {
return mTaskWrapper.getConfig();
}
@Override public FtpThreadTask call() throws Exception {
super.call();
//当前子线程的下载位置
mChildCurrentLocation = mConfig.START_LOCATION;
FTPClient client = null;
BufferedRandomAccessFile file = null;
try {
ALog.d(TAG,
String.format("任务【%s】线程__%s__开始上传【开始位置 : %s,结束位置:%s】", mConfig.TEMP_FILE.getName(),
mConfig.THREAD_ID, mConfig.START_LOCATION, mConfig.END_LOCATION));
client = createClient();
if (client == null) {
return this;
}
initPath();
client.makeDirectory(dir);
client.changeWorkingDirectory(dir);
client.setRestartOffset(mConfig.START_LOCATION);
int reply = client.getReplyCode();
if (!FTPReply.isPositivePreliminary(reply) && reply != FTPReply.FILE_ACTION_OK) {
fail(mChildCurrentLocation,
new AriaIOException(TAG,
String.format("文件上传错误,错误码为:%s, msg:%s, filePath: %s", reply,
client.getReplyString(), mEntity.getFilePath())));
client.disconnect();
return this;
}
file = new BufferedRandomAccessFile(mConfig.TEMP_FILE, "rwd", getTaskConfig().getBuffSize());
if (mConfig.START_LOCATION != 0) {
//file.skipBytes((int) mConfig.START_LOCATION);
file.seek(mConfig.START_LOCATION);
}
boolean complete = upload(client, file);
if (!complete || isBreak()) {
return this;
}
ALog.i(TAG,
String.format("任务【%s】线程__%s__上传完毕", mConfig.TEMP_FILE.getName(), mConfig.THREAD_ID));
writeConfig(true, mConfig.END_LOCATION);
STATE.COMPLETE_THREAD_NUM++;
if (STATE.isComplete()) {
STATE.TASK_RECORD.deleteData();
STATE.isRunning = false;
mListener.onComplete();
}
if (STATE.isFail()) {
STATE.isRunning = false;
mListener.onFail(false, new TaskException(TAG,
String.format("上传失败,filePath: %s, uploadUrl: %s", mEntity.getFilePath(), mConfig.URL)));
}
} catch (IOException e) {
fail(mChildCurrentLocation, new AriaIOException(TAG,
String.format("上传失败,filePath: %s, uploadUrl: %s", mEntity.getFilePath(), mConfig.URL)));
} catch (Exception e) {
fail(mChildCurrentLocation, new AriaIOException(TAG, null, e));
} finally {
try {
if (file != null) {
file.close();
}
if (client != null && client.isConnected()) {
client.disconnect();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return this;
}
private void initPath() throws UnsupportedEncodingException {
dir = new String(mTaskWrapper.asFtp().getUrlEntity().remotePath.getBytes(charSet),
SERVER_CHARSET);
remotePath = new String(
("/"
+ mTaskWrapper.asFtp().getUrlEntity().remotePath
+ "/"
+ mEntity.getFileName()).getBytes(
charSet),
SERVER_CHARSET);
}
/**
* 上传
*
* @return {@code true}上传成功{@code false} 上传失败
*/
private boolean upload(final FTPClient client, final BufferedRandomAccessFile bis)
throws IOException {
try {
ALog.d(TAG, String.format("remotePath: %s", remotePath));
client.storeFile(remotePath, new FtpFISAdapter(bis), new OnFtpInputStreamListener() {
boolean isStoped = false;
@Override public void onFtpInputStream(FTPClient client, long totalBytesTransferred,
int bytesTransferred, long streamSize) {
try {
if (isBreak() && !isStoped) {
isStoped = true;
client.abor();
}
if (mSpeedBandUtil != null) {
mSpeedBandUtil.limitNextBytes(bytesTransferred);
}
progress(bytesTransferred);
} catch (IOException e) {
e.printStackTrace();
}
}
});
} catch (IOException e) {
String msg = String.format("文件上传错误,错误码为:%s, msg:%s, filePath: %s", client.getReplyCode(),
client.getReplyString(), mEntity.getFilePath());
if (client.isConnected()) {
client.disconnect();
}
if (e.getMessage().contains("AriaIOException caught while copying")) {
e.printStackTrace();
} else {
fail(mChildCurrentLocation,
new AriaIOException(TAG, msg, e));
}
return false;
}
int reply = client.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
if (reply != FTPReply.TRANSFER_ABORTED) {
fail(mChildCurrentLocation,
new AriaIOException(TAG,
String.format("文件上传错误,错误码为:%s, msg:%s, filePath: %s", reply,
client.getReplyString(), mEntity.getFilePath())));
}
if (client.isConnected()) {
client.disconnect();
}
return false;
}
return true;
}
}
/*
* 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.upload.uploader;
import aria.apache.commons.net.ftp.FTPClient;
import aria.apache.commons.net.ftp.FTPReply;
import aria.apache.commons.net.ftp.OnFtpInputStreamListener;
import com.arialyy.aria.core.common.StateConstance;
import com.arialyy.aria.core.common.SubThreadConfig;
import com.arialyy.aria.core.common.ftp.AbsFtpThreadTask;
import com.arialyy.aria.core.config.BaseTaskConfig;
import com.arialyy.aria.core.config.DownloadConfig;
import com.arialyy.aria.core.config.UploadConfig;
import com.arialyy.aria.core.inf.IEventListener;
import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.core.upload.UTaskWrapper;
import com.arialyy.aria.exception.AriaIOException;
import com.arialyy.aria.exception.TaskException;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.BufferedRandomAccessFile;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
/**
* Created by Aria.Lao on 2017/7/28. FTP 单线程上传任务需要FTP 服务器给用户打开append和write的权限
*/
class FtpThreadTask extends AbsFtpThreadTask<UploadEntity, UTaskWrapper> {
private final String TAG = "FtpThreadTask";
private String dir, remotePath;
FtpThreadTask(StateConstance constance, IEventListener listener,
SubThreadConfig<UTaskWrapper> info) {
super(constance, listener, info);
}
@Override public int getMaxSpeed() {
return getTaskConfig().getMaxSpeed();
}
@Override protected UploadConfig getTaskConfig() {
return mTaskWrapper.getConfig();
}
@Override public FtpThreadTask call() throws Exception {
super.call();
//当前子线程的下载位置
mChildCurrentLocation = mConfig.START_LOCATION;
FTPClient client = null;
BufferedRandomAccessFile file = null;
try {
ALog.d(TAG,
String.format("任务【%s】线程__%s__开始上传【开始位置 : %s,结束位置:%s】", mConfig.TEMP_FILE.getName(),
mConfig.THREAD_ID, mConfig.START_LOCATION, mConfig.END_LOCATION));
client = createClient();
if (client == null) {
return this;
}
initPath();
client.makeDirectory(dir);
client.changeWorkingDirectory(dir);
client.setRestartOffset(mConfig.START_LOCATION);
int reply = client.getReplyCode();
if (!FTPReply.isPositivePreliminary(reply) && reply != FTPReply.FILE_ACTION_OK) {
fail(mChildCurrentLocation,
new AriaIOException(TAG,
String.format("文件上传错误,错误码为:%s, msg:%s, filePath: %s", reply,
client.getReplyString(), mEntity.getFilePath())));
client.disconnect();
return this;
}
file = new BufferedRandomAccessFile(mConfig.TEMP_FILE, "rwd", getTaskConfig().getBuffSize());
if (mConfig.START_LOCATION != 0) {
//file.skipBytes((int) mConfig.START_LOCATION);
file.seek(mConfig.START_LOCATION);
}
boolean complete = upload(client, file);
if (!complete || isBreak()) {
return this;
}
ALog.i(TAG,
String.format("任务【%s】线程__%s__上传完毕", mConfig.TEMP_FILE.getName(), mConfig.THREAD_ID));
writeConfig(true, mConfig.END_LOCATION);
STATE.COMPLETE_THREAD_NUM++;
if (STATE.isComplete()) {
STATE.TASK_RECORD.deleteData();
STATE.isRunning = false;
mListener.onComplete();
}
if (STATE.isFail()) {
STATE.isRunning = false;
mListener.onFail(false, new TaskException(TAG,
String.format("上传失败,filePath: %s, uploadUrl: %s", mEntity.getFilePath(), mConfig.URL)));
}
} catch (IOException e) {
fail(mChildCurrentLocation, new AriaIOException(TAG,
String.format("上传失败,filePath: %s, uploadUrl: %s", mEntity.getFilePath(), mConfig.URL)));
} catch (Exception e) {
fail(mChildCurrentLocation, new AriaIOException(TAG, null, e));
} finally {
try {
if (file != null) {
file.close();
}
if (client != null && client.isConnected()) {
client.disconnect();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return this;
}
private void initPath() throws UnsupportedEncodingException {
dir = new String(mTaskWrapper.asFtp().getUrlEntity().remotePath.getBytes(charSet),
SERVER_CHARSET);
remotePath = new String(String.format("%s/%s", mTaskWrapper.asFtp().getUrlEntity().remotePath,
mEntity.getFileName()).getBytes(charSet), SERVER_CHARSET);
}
/**
* 上传
*
* @return {@code true}上传成功{@code false} 上传失败
*/
private boolean upload(final FTPClient client, final BufferedRandomAccessFile bis)
throws IOException {
try {
ALog.d(TAG, String.format("remotePath: %s", remotePath));
client.storeFile(remotePath, new FtpFISAdapter(bis), new OnFtpInputStreamListener() {
boolean isStoped = false;
@Override public void onFtpInputStream(FTPClient client, long totalBytesTransferred,
int bytesTransferred, long streamSize) {
try {
if (isBreak() && !isStoped) {
isStoped = true;
client.abor();
}
if (mSpeedBandUtil != null) {
mSpeedBandUtil.limitNextBytes(bytesTransferred);
}
progress(bytesTransferred);
} catch (IOException e) {
e.printStackTrace();
}
}
});
} catch (IOException e) {
String msg = String.format("文件上传错误,错误码为:%s, msg:%s, filePath: %s", client.getReplyCode(),
client.getReplyString(), mEntity.getFilePath());
if (client.isConnected()) {
client.disconnect();
}
if (e.getMessage().contains("AriaIOException caught while copying")) {
e.printStackTrace();
} else {
fail(mChildCurrentLocation,
new AriaIOException(TAG, msg, e));
}
return false;
}
int reply = client.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
if (reply != FTPReply.TRANSFER_ABORTED) {
fail(mChildCurrentLocation,
new AriaIOException(TAG,
String.format("文件上传错误,错误码为:%s, msg:%s, filePath: %s", reply,
client.getReplyString(), mEntity.getFilePath())));
}
if (client.isConnected()) {
client.disconnect();
}
return false;
}
return true;
}
}

@ -0,0 +1,24 @@
/*
* 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.exception;
public class ParamException extends RuntimeException {
private static final String ARIA_NET_EXCEPTION = "Aria Params Exception:";
public ParamException(String message) {
super(String.format("%s%s", ARIA_NET_EXCEPTION, message));
}
}

@ -1,290 +1,290 @@
/*
* 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.orm;
import java.util.ArrayList;
import java.util.List;
/**
* Created by lyy on 2015/11/2. 所有数据库实体父类
*/
public abstract class DbEntity {
private static final Object LOCK = new Object();
protected long rowID = -1;
protected DbEntity() {
}
/**
* 查询关联数据
* <code>
* DbEntity.findRelationData(DGEntityWrapper.class, "downloadUrl=?", downloadUrl);
* </code>
*
* @param expression 查询条件
*/
public static <T extends AbsDbWrapper> List<T> findRelationData(Class<T> clazz,
String... expression) {
return DelegateWrapper.getInstance().findRelationData(clazz, expression);
}
/**
* 分页查询关联数据
*
* <code>
* DbEntity.findRelationData(DGEntityWrapper.class, 0, 10, "downloadUrl=?", downloadUrl);
* </code>
*
* @param expression 查询条件
* @param page 需要查询的页数从1开始如果page小于1 num 小于1返回null
* @param num 每页返回的数量
* @return 没有数据返回null如果页数大于总页数返回null
*/
public static <T extends AbsDbWrapper> List<T> findRelationData(Class<T> clazz, int page, int num,
String... expression) {
if (page < 1 || num < 1) {
return null;
}
return DelegateWrapper.getInstance().findRelationData(clazz, page, num, expression);
}
/**
* 检查某个字段的值是否存在
*
* @param expression 字段和值"downloadPath=?"
* @return {@code true}该字段的对应的value已存在
*/
public static boolean checkDataExist(Class clazz, String... expression) {
return DelegateWrapper.getInstance().checkDataExist(clazz, expression);
}
/**
* 清空表数据
*/
public static <T extends DbEntity> void clean(Class<T> clazz) {
DelegateWrapper.getInstance().clean(clazz);
}
/**
* 直接执行sql语句
*/
public static void exeSql(String sql) {
DelegateWrapper.getInstance().exeSql(sql);
}
/**
* 查询所有数据
*
* @return 没有数据返回null
*/
public static <T extends DbEntity> List<T> findAllData(Class<T> clazz) {
return DelegateWrapper.getInstance().findAllData(clazz);
}
/**
* 查询第一条数据
*/
public static <T extends DbEntity> T findFirst(Class<T> clazz) {
List<T> list = findAllData(clazz);
return (list == null || list.size() == 0) ? null : list.get(0);
}
/**
* 查询一组数据
* <code>
* DbEntity.findFirst(DownloadEntity.class, "downloadUrl=?", downloadUrl);
* </code>
*
* @return 没有数据返回null
*/
public static <T extends DbEntity> List<T> findDatas(Class<T> clazz, String... expression) {
return DelegateWrapper.getInstance().findData(clazz, expression);
}
/**
* 分页查询数据
* <code>
* DbEntity.findFirst(DownloadEntity.class, 0, 10, "downloadUrl=?", downloadUrl);
* </code>
*
* @param page 需要查询的页数从1开始如果page小于1 num 小于1返回null
* @param num 每页返回的数量
* @return 没有数据返回null如果页数大于总页数返回null
*/
public static <T extends DbEntity> List<T> findDatas(Class<T> clazz, int page, int num,
String... expression) {
if (page < 1 || num < 1) {
return null;
}
return DelegateWrapper.getInstance().findData(clazz, page, num, expression);
}
/**
* 模糊查询一组数据
* <code>
* DbEntity.findDataByFuzzy(DownloadEntity.class, "downloadUrl like http://");
* </code>
*
* @return 没有数据返回null
*/
public static <T extends DbEntity> List<T> findDataByFuzzy(Class<T> clazz, String conditions) {
return DelegateWrapper.getInstance().findDataByFuzzy(clazz, conditions);
}
/**
* 模糊查询一组数据
* <code>
* DbEntity.findDataByFuzzy(DownloadEntity.class, 0, 10, "downloadUrl like http://");
* </code>
*
* @param page 需要查询的页数从1开始如果page小于1 num 小于1返回null
* @param num 每页返回的数量
* @return 没有数据返回null如果页数大于总页数返回null
*/
public static <T extends DbEntity> List<T> findDataByFuzzy(Class<T> clazz, int page, int num,
String conditions) {
return DelegateWrapper.getInstance().findDataByFuzzy(clazz, page, num, conditions);
}
/**
* 查询一行数据
* <code>
* DbEntity.findFirst(DownloadEntity.class, "downloadUrl=?", downloadUrl);
* </code>
*
* @return 没有数据返回null
*/
public static <T extends DbEntity> T findFirst(Class<T> clazz, String... expression) {
DelegateWrapper util = DelegateWrapper.getInstance();
List<T> datas = util.findData(clazz, expression);
return datas == null ? null : datas.size() > 0 ? datas.get(0) : null;
}
/**
* 插入多条数据
*/
public static void insertManyData(List<DbEntity> entities) {
checkListData(entities);
DelegateWrapper.getInstance().insertManyData(entities);
}
/**
* 修改多条数据
*/
public static void updateManyData(List<DbEntity> entities) {
checkListData(entities);
DelegateWrapper.getInstance().updateManyData(entities);
}
/**
* 保存多条数据通过rowID来判断记录存在以否如果数据库已有记录则更新该记录如果数据库中没有记录则保存该记录
*/
public static void saveAll(List<DbEntity> entities) {
checkListData(entities);
List<DbEntity> insertD = new ArrayList<>();
List<DbEntity> updateD = new ArrayList<>();
DelegateWrapper wrapper = DelegateWrapper.getInstance();
for (DbEntity entity : entities) {
if (entity.rowID == -1) {
insertD.add(entity);
continue;
}
if (wrapper.isExist(entity.getClass(), entity.rowID)) {
insertD.add(entity);
} else {
updateD.add(entity);
}
}
if (!insertD.isEmpty()) {
wrapper.insertManyData(insertD);
} else {
wrapper.updateManyData(updateD);
}
}
/**
* 检查批量操作的列表数据如果数据为空抛出{@link NullPointerException}
*/
private static void checkListData(List<DbEntity> entities) {
if (entities == null || entities.isEmpty()) {
throw new NullPointerException("列表数据为空");
}
}
/**
* 删除当前数据
*/
public void deleteData() {
deleteData(getClass(), "rowid=?", rowID + "");
}
/**
* 根据条件删除数据
* <code>
* DbEntity.deleteData(DownloadEntity.class, "downloadUrl=?", downloadUrl);
* </code>
*/
public static <T extends DbEntity> void deleteData(Class<T> clazz, String... expression) {
DelegateWrapper util = DelegateWrapper.getInstance();
util.delData(clazz, expression);
}
/**
* 修改数据
*/
public void update() {
DelegateWrapper.getInstance().updateData(this);
}
/**
* 保存自身如果表中已经有数据则更新数据否则插入数据 只有 target中checkEntity成功后才能保存创建实体部分也不允许保存
*/
public void save() {
synchronized (LOCK) {
if (thisIsExist()) {
update();
} else {
insert();
}
}
}
/**
* 查找数据在表中是否存在
*/
private boolean thisIsExist() {
DelegateWrapper util = DelegateWrapper.getInstance();
return rowID != -1 && util.isExist(getClass(), rowID);
}
/**
* 表是否存在
*
* @return {@code true} 存在
*/
public static boolean tableExists(Class<DbEntity> clazz) {
return DelegateWrapper.getInstance().tableExists(clazz);
}
/**
* 插入数据只有 target中checkEntity成功后才能插入创建实体部分也不允许操作
*/
public void insert() {
DelegateWrapper.getInstance().insertData(this);
}
/*
* 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.orm;
import java.util.ArrayList;
import java.util.List;
/**
* Created by lyy on 2015/11/2. 所有数据库实体父类
*/
public abstract class DbEntity {
private static final Object LOCK = new Object();
protected long rowID = -1;
protected DbEntity() {
}
/**
* 查询关联数据
* <code>
* DbEntity.findRelationData(DGEntityWrapper.class, "downloadUrl=?", downloadUrl);
* </code>
*
* @param expression 查询条件
*/
public static <T extends AbsDbWrapper> List<T> findRelationData(Class<T> clazz,
String... expression) {
return DelegateWrapper.getInstance().findRelationData(clazz, expression);
}
/**
* 分页查询关联数据
*
* <code>
* DbEntity.findRelationData(DGEntityWrapper.class, 0, 10, "downloadUrl=?", downloadUrl);
* </code>
*
* @param expression 查询条件
* @param page 需要查询的页数从1开始如果page小于1 num 小于1返回null
* @param num 每页返回的数量
* @return 没有数据返回null如果页数大于总页数返回null
*/
public static <T extends AbsDbWrapper> List<T> findRelationData(Class<T> clazz, int page, int num,
String... expression) {
if (page < 1 || num < 1) {
return null;
}
return DelegateWrapper.getInstance().findRelationData(clazz, page, num, expression);
}
/**
* 检查某个字段的值是否存在
*
* @param expression 字段和值"downloadPath=?"
* @return {@code true}该字段的对应的value已存在
*/
public static boolean checkDataExist(Class clazz, String... expression) {
return DelegateWrapper.getInstance().checkDataExist(clazz, expression);
}
/**
* 清空表数据
*/
public static <T extends DbEntity> void clean(Class<T> clazz) {
DelegateWrapper.getInstance().clean(clazz);
}
/**
* 直接执行sql语句
*/
public static void exeSql(String sql) {
DelegateWrapper.getInstance().exeSql(sql);
}
/**
* 查询所有数据
*
* @return 没有数据返回null
*/
public static <T extends DbEntity> List<T> findAllData(Class<T> clazz) {
return DelegateWrapper.getInstance().findAllData(clazz);
}
/**
* 查询第一条数据
*/
public static <T extends DbEntity> T findFirst(Class<T> clazz) {
List<T> list = findAllData(clazz);
return (list == null || list.size() == 0) ? null : list.get(0);
}
/**
* 查询一组数据
* <code>
* DbEntity.findFirst(DownloadEntity.class, "downloadUrl=?", downloadUrl);
* </code>
*
* @return 没有数据返回null
*/
public static <T extends DbEntity> List<T> findDatas(Class<T> clazz, String... expression) {
return DelegateWrapper.getInstance().findData(clazz, expression);
}
/**
* 分页查询数据
* <code>
* DbEntity.findFirst(DownloadEntity.class, 0, 10, "downloadUrl=?", downloadUrl);
* </code>
*
* @param page 需要查询的页数从1开始如果page小于1 num 小于1返回null
* @param num 每页返回的数量
* @return 没有数据返回null如果页数大于总页数返回null
*/
public static <T extends DbEntity> List<T> findDatas(Class<T> clazz, int page, int num,
String... expression) {
if (page < 1 || num < 1) {
return null;
}
return DelegateWrapper.getInstance().findData(clazz, page, num, expression);
}
/**
* 模糊查询一组数据
* <code>
* DbEntity.findDataByFuzzy(DownloadEntity.class, "downloadUrl like http://");
* </code>
*
* @return 没有数据返回null
*/
public static <T extends DbEntity> List<T> findDataByFuzzy(Class<T> clazz, String conditions) {
return DelegateWrapper.getInstance().findDataByFuzzy(clazz, conditions);
}
/**
* 模糊查询一组数据
* <code>
* DbEntity.findDataByFuzzy(DownloadEntity.class, 0, 10, "downloadUrl like http://");
* </code>
*
* @param page 需要查询的页数从1开始如果page小于1 num 小于1返回null
* @param num 每页返回的数量
* @return 没有数据返回null如果页数大于总页数返回null
*/
public static <T extends DbEntity> List<T> findDataByFuzzy(Class<T> clazz, int page, int num,
String conditions) {
return DelegateWrapper.getInstance().findDataByFuzzy(clazz, page, num, conditions);
}
/**
* 查询一行数据
* <code>
* DbEntity.findFirst(DownloadEntity.class, "downloadUrl=?", downloadUrl);
* </code>
*
* @return 没有数据返回null
*/
public static <T extends DbEntity> T findFirst(Class<T> clazz, String... expression) {
DelegateWrapper util = DelegateWrapper.getInstance();
List<T> datas = util.findData(clazz, expression);
return datas == null ? null : datas.size() > 0 ? datas.get(0) : null;
}
/**
* 插入多条数据
*/
public static void insertManyData(List<DbEntity> entities) {
checkListData(entities);
DelegateWrapper.getInstance().insertManyData(entities);
}
/**
* 修改多条数据
*/
public static void updateManyData(List<DbEntity> entities) {
checkListData(entities);
DelegateWrapper.getInstance().updateManyData(entities);
}
/**
* 保存多条数据通过rowID来判断记录存在以否如果数据库已有记录则更新该记录如果数据库中没有记录则保存该记录
*/
public static <T extends DbEntity> void saveAll(List<T> entities) {
checkListData(entities);
List<DbEntity> insertD = new ArrayList<>();
List<DbEntity> updateD = new ArrayList<>();
DelegateWrapper wrapper = DelegateWrapper.getInstance();
for (DbEntity entity : entities) {
if (entity.rowID == -1) {
insertD.add(entity);
continue;
}
if (wrapper.isExist(entity.getClass(), entity.rowID)) {
updateD.add(entity);
} else {
insertD.add(entity);
}
}
if (!insertD.isEmpty()) {
wrapper.insertManyData(insertD);
} else {
wrapper.updateManyData(updateD);
}
}
/**
* 检查批量操作的列表数据如果数据为空抛出{@link NullPointerException}
*/
private static <T extends DbEntity> void checkListData(List<T> entities) {
if (entities == null || entities.isEmpty()) {
throw new NullPointerException("列表数据为空");
}
}
/**
* 删除当前数据
*/
public void deleteData() {
deleteData(getClass(), "rowid=?", rowID + "");
}
/**
* 根据条件删除数据
* <code>
* DbEntity.deleteData(DownloadEntity.class, "downloadUrl=?", downloadUrl);
* </code>
*/
public static <T extends DbEntity> void deleteData(Class<T> clazz, String... expression) {
DelegateWrapper util = DelegateWrapper.getInstance();
util.delData(clazz, expression);
}
/**
* 修改数据
*/
public void update() {
DelegateWrapper.getInstance().updateData(this);
}
/**
* 保存自身如果表中已经有数据则更新数据否则插入数据 只有 target中checkEntity成功后才能保存创建实体部分也不允许保存
*/
public void save() {
synchronized (LOCK) {
if (thisIsExist()) {
update();
} else {
insert();
}
}
}
/**
* 查找数据在表中是否存在
*/
private boolean thisIsExist() {
DelegateWrapper util = DelegateWrapper.getInstance();
return rowID != -1 && util.isExist(getClass(), rowID);
}
/**
* 表是否存在
*
* @return {@code true} 存在
*/
public static boolean tableExists(Class<DbEntity> clazz) {
return DelegateWrapper.getInstance().tableExists(clazz);
}
/**
* 插入数据只有 target中checkEntity成功后才能插入创建实体部分也不允许操作
*/
public void insert() {
DelegateWrapper.getInstance().insertData(this);
}
}

@ -1,238 +1,254 @@
/*
* 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.util;
import android.text.TextUtils;
import com.arialyy.aria.core.download.DTaskWrapper;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.inf.AbsTaskWrapper;
import com.arialyy.aria.core.upload.UTaskWrapper;
import com.arialyy.aria.core.upload.UploadEntity;
import java.io.File;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Created by Lyy on 2016/9/23.
* 检查帮助类
*/
public class CheckUtil {
private static final String TAG = "CheckUtil";
/**
* 判空
*/
public static void checkNull(Object obj) {
if (obj == null) throw new IllegalArgumentException("不能传入空对象");
}
/**
* 检查分页数据需要查询的页数从1开始如果page小于1 num 小于1则抛出{@link NullPointerException}
* @param page 从1 开始
* @param num 每页数量
*/
public static void checkPageParams(int page, int num){
if (page < 1 || num < 1) throw new NullPointerException("page和num不能小于1");
}
/**
* 检查sql的expression是否合法
*/
public static void checkSqlExpression(String... expression) {
if (expression.length == 0) {
throw new IllegalArgumentException("sql语句表达式不能为null");
}
if (expression.length == 1) {
throw new IllegalArgumentException("表达式需要写入参数");
}
String where = expression[0];
if (!where.contains("?")) {
throw new IllegalArgumentException("请在where语句的'='后编写?");
}
Pattern pattern = Pattern.compile("\\?");
Matcher matcher = pattern.matcher(where);
int count = 0;
while (matcher.find()) {
count++;
}
if (count < expression.length - 1) {
throw new IllegalArgumentException("条件语句的?个数不能小于参数个数");
}
if (count > expression.length - 1) {
throw new IllegalArgumentException("条件语句的?个数不能大于参数个数");
}
}
/**
* 检查下载实体
*/
public static void checkDownloadEntity(DownloadEntity entity) {
checkUrlInvalidThrow(entity.getUrl());
entity.setUrl(entity.getUrl());
checkPath(entity.getDownloadPath());
}
/**
* 检测下载链接是否为null
*/
public static void checkPath(String path) {
if (TextUtils.isEmpty(path)) {
throw new IllegalArgumentException("保存路径不能为null");
}
}
/**
* 检测url是否合法如果url不合法将抛异常
*/
public static void checkUrlInvalidThrow(String url) {
if (TextUtils.isEmpty(url)) {
throw new IllegalArgumentException("url不能为null");
} else if (!url.startsWith("http") && !url.startsWith("ftp")) {
throw new IllegalArgumentException("url错误");
}
int index = url.indexOf("://");
if (index == -1) {
throw new IllegalArgumentException("url不合法");
}
}
/**
* 检测url是否合法
*
* @return {@code true} 合法{@code false} 非法
*/
public static boolean checkUrl(String url) {
if (TextUtils.isEmpty(url)) {
ALog.e(TAG, "url不能为null");
return false;
} else if (!url.startsWith("http") && !url.startsWith("ftp")) {
ALog.e(TAG, "url【" + url + "】错误");
return false;
}
int index = url.indexOf("://");
if (index == -1) {
ALog.e(TAG, "url【" + url + "】不合法");
}
return true;
}
/**
* 检测下载链接组是否为null
*/
public static void checkDownloadUrls(List<String> urls) {
if (urls == null || urls.isEmpty()) {
throw new IllegalArgumentException("链接组不能为null");
}
}
/**
* 检查下载任务组保存路径
*/
public static void checkDownloadPaths(List<String> paths) {
if (paths == null || paths.isEmpty()) {
throw new IllegalArgumentException("链接保存路径不能为null");
}
}
/**
* 检测上传地址是否为null
*/
public static void checkUploadPath(String uploadPath) {
if (TextUtils.isEmpty(uploadPath)) {
throw new IllegalArgumentException("上传地址不能为null");
}
File file = new File(uploadPath);
if (!file.exists()) {
throw new IllegalArgumentException("上传文件不存在");
}
}
/**
* 检查任务实体
*/
public static void checkTaskEntity(AbsTaskWrapper entity) {
if (entity instanceof DTaskWrapper) {
checkDownloadTaskEntity(((DTaskWrapper) entity).getEntity());
} else if (entity instanceof UTaskWrapper) {
checkUploadTaskEntity(((UTaskWrapper) entity).getEntity());
}
}
/**
* 检查命令实体
*
* @param checkType 删除命令和停止命令不需要检查下载链接和保存路径
* @return {@code false}实体无效
*/
public static boolean checkCmdEntity(AbsTaskWrapper entity, boolean checkType) {
boolean b = false;
if (entity instanceof DTaskWrapper) {
DownloadEntity entity1 = ((DTaskWrapper) entity).getEntity();
if (entity1 == null) {
ALog.e(TAG, "下载实体不能为空");
} else if (checkType && TextUtils.isEmpty(entity1.getUrl())) {
ALog.e(TAG, "下载链接不能为空");
} else if (checkType && TextUtils.isEmpty(entity1.getDownloadPath())) {
ALog.e(TAG, "保存路径不能为空");
} else {
b = true;
}
} else if (entity instanceof UTaskWrapper) {
UploadEntity entity1 = ((UTaskWrapper) entity).getEntity();
if (entity1 == null) {
ALog.e(TAG, "上传实体不能为空");
} else if (TextUtils.isEmpty(entity1.getFilePath())) {
ALog.e(TAG, "上传文件路径不能为空");
} else {
b = true;
}
}
return b;
}
/**
* 检查上传实体是否合法
*/
private static void checkUploadTaskEntity(UploadEntity entity) {
if (entity == null) {
throw new NullPointerException("上传实体不能为空");
} else if (TextUtils.isEmpty(entity.getFilePath())) {
throw new IllegalArgumentException("上传文件路径不能为空");
} else if (TextUtils.isEmpty(entity.getFileName())) {
throw new IllegalArgumentException("上传文件名不能为空");
}
}
/**
* 检测下载实体是否合法
* 合法(true)
*
* @param entity 下载实体
*/
private static void checkDownloadTaskEntity(DownloadEntity entity) {
if (entity == null) {
throw new NullPointerException("下载实体不能为空");
} else if (TextUtils.isEmpty(entity.getUrl())) {
throw new IllegalArgumentException("下载链接不能为空");
} else if (TextUtils.isEmpty(entity.getFileName())) {
throw new NullPointerException("文件名不能为null");
} else if (TextUtils.isEmpty(entity.getDownloadPath())) {
throw new NullPointerException("文件保存路径不能为null");
}
}
/*
* 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.util;
import android.text.TextUtils;
import com.arialyy.aria.core.download.DTaskWrapper;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.inf.AbsTaskWrapper;
import com.arialyy.aria.core.upload.UTaskWrapper;
import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.exception.ParamException;
import java.io.File;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Created by Lyy on 2016/9/23.
* 检查帮助类
*/
public class CheckUtil {
private static final String TAG = "CheckUtil";
/**
* 检查ftp上传路径如果ftp上传路径为空抛出空指针异常
* 如果ftp上传路径不是以"ftp""sftp"抛出参数异常
*
* @param ftpUrl ftp上传路径
*/
public static void checkFtpUploadUrl(String ftpUrl) {
if (TextUtils.isEmpty(ftpUrl)) {
throw new ParamException("ftp上传路径为空");
} else if (!ftpUrl.startsWith("ftp") || !ftpUrl.startsWith("sftp")) {
throw new ParamException("ftp上传路径无效");
}
}
/**
* 判空
*/
public static void checkNull(Object obj) {
if (obj == null) throw new IllegalArgumentException("不能传入空对象");
}
/**
* 检查分页数据需要查询的页数从1开始如果page小于1 num 小于1则抛出{@link NullPointerException}
*
* @param page 从1 开始
* @param num 每页数量
*/
public static void checkPageParams(int page, int num) {
if (page < 1 || num < 1) throw new NullPointerException("page和num不能小于1");
}
/**
* 检查sql的expression是否合法
*/
public static void checkSqlExpression(String... expression) {
if (expression.length == 0) {
throw new IllegalArgumentException("sql语句表达式不能为null");
}
if (expression.length == 1) {
throw new IllegalArgumentException("表达式需要写入参数");
}
String where = expression[0];
if (!where.contains("?")) {
throw new IllegalArgumentException("请在where语句的'='后编写?");
}
Pattern pattern = Pattern.compile("\\?");
Matcher matcher = pattern.matcher(where);
int count = 0;
while (matcher.find()) {
count++;
}
if (count < expression.length - 1) {
throw new IllegalArgumentException("条件语句的?个数不能小于参数个数");
}
if (count > expression.length - 1) {
throw new IllegalArgumentException("条件语句的?个数不能大于参数个数");
}
}
/**
* 检查下载实体
*/
public static void checkDownloadEntity(DownloadEntity entity) {
checkUrlInvalidThrow(entity.getUrl());
entity.setUrl(entity.getUrl());
checkPath(entity.getDownloadPath());
}
/**
* 检测下载链接是否为null
*/
public static void checkPath(String path) {
if (TextUtils.isEmpty(path)) {
throw new IllegalArgumentException("保存路径不能为null");
}
}
/**
* 检测url是否合法如果url不合法将抛异常
*/
public static void checkUrlInvalidThrow(String url) {
if (TextUtils.isEmpty(url)) {
throw new IllegalArgumentException("url不能为null");
} else if (!url.startsWith("http") && !url.startsWith("ftp")) {
throw new IllegalArgumentException("url错误");
}
int index = url.indexOf("://");
if (index == -1) {
throw new IllegalArgumentException("url不合法");
}
}
/**
* 检测url是否合法
*
* @return {@code true} 合法{@code false} 非法
*/
public static boolean checkUrl(String url) {
if (TextUtils.isEmpty(url)) {
ALog.e(TAG, "url不能为null");
return false;
} else if (!url.startsWith("http") && !url.startsWith("ftp")) {
ALog.e(TAG, "url【" + url + "】错误");
return false;
}
int index = url.indexOf("://");
if (index == -1) {
ALog.e(TAG, "url【" + url + "】不合法");
}
return true;
}
/**
* 检测下载链接组是否为null
*/
public static void checkDownloadUrls(List<String> urls) {
if (urls == null || urls.isEmpty()) {
throw new IllegalArgumentException("链接组不能为null");
}
}
/**
* 检查下载任务组保存路径
*/
public static void checkDownloadPaths(List<String> paths) {
if (paths == null || paths.isEmpty()) {
throw new IllegalArgumentException("链接保存路径不能为null");
}
}
/**
* 检测上传地址是否为null
*/
public static void checkUploadPath(String uploadPath) {
if (TextUtils.isEmpty(uploadPath)) {
throw new IllegalArgumentException("上传地址不能为null");
}
File file = new File(uploadPath);
if (!file.exists()) {
throw new IllegalArgumentException("上传文件不存在");
}
}
/**
* 检查任务实体
*/
public static void checkTaskEntity(AbsTaskWrapper entity) {
if (entity instanceof DTaskWrapper) {
checkDownloadTaskEntity(((DTaskWrapper) entity).getEntity());
} else if (entity instanceof UTaskWrapper) {
checkUploadTaskEntity(((UTaskWrapper) entity).getEntity());
}
}
/**
* 检查命令实体
*
* @param checkType 删除命令和停止命令不需要检查下载链接和保存路径
* @return {@code false}实体无效
*/
public static boolean checkCmdEntity(AbsTaskWrapper entity, boolean checkType) {
boolean b = false;
if (entity instanceof DTaskWrapper) {
DownloadEntity entity1 = ((DTaskWrapper) entity).getEntity();
if (entity1 == null) {
ALog.e(TAG, "下载实体不能为空");
} else if (checkType && TextUtils.isEmpty(entity1.getUrl())) {
ALog.e(TAG, "下载链接不能为空");
} else if (checkType && TextUtils.isEmpty(entity1.getDownloadPath())) {
ALog.e(TAG, "保存路径不能为空");
} else {
b = true;
}
} else if (entity instanceof UTaskWrapper) {
UploadEntity entity1 = ((UTaskWrapper) entity).getEntity();
if (entity1 == null) {
ALog.e(TAG, "上传实体不能为空");
} else if (TextUtils.isEmpty(entity1.getFilePath())) {
ALog.e(TAG, "上传文件路径不能为空");
} else {
b = true;
}
}
return b;
}
/**
* 检查上传实体是否合法
*/
private static void checkUploadTaskEntity(UploadEntity entity) {
if (entity == null) {
throw new NullPointerException("上传实体不能为空");
} else if (TextUtils.isEmpty(entity.getFilePath())) {
throw new IllegalArgumentException("上传文件路径不能为空");
} else if (TextUtils.isEmpty(entity.getFileName())) {
throw new IllegalArgumentException("上传文件名不能为空");
}
}
/**
* 检测下载实体是否合法
* 合法(true)
*
* @param entity 下载实体
*/
private static void checkDownloadTaskEntity(DownloadEntity entity) {
if (entity == null) {
throw new NullPointerException("下载实体不能为空");
} else if (TextUtils.isEmpty(entity.getUrl())) {
throw new IllegalArgumentException("下载链接不能为空");
} else if (TextUtils.isEmpty(entity.getFileName())) {
throw new NullPointerException("文件名不能为null");
} else if (TextUtils.isEmpty(entity.getDownloadPath())) {
throw new NullPointerException("文件保存路径不能为null");
}
}
}

File diff suppressed because it is too large Load Diff

@ -1,4 +1,8 @@
## 开发日志
+ v_3.6.4
- 优化任务接收器的代码结构
- 修复`DbEntity.saveAll()`失败的问题
- 修复分块任务重命名失败的问题
+ v_3.6.3 (2019/4/2)
- fix bug https://github.com/AriaLyy/Aria/issues/377
+ v_3.6.2 (2019/4/1)

@ -1,161 +1,161 @@
<?xml version="1.0" encoding="utf-8"?>
<aria>
<!--注意,修改该配置文件中的属性会覆盖代码中所设置的属性-->
<!--Aria框架配置-->
<app>
<!--是否使用AriaCrashHandler来捕获异常,异常日志保存在:/mnt/sdcard/Android/data/{package_name}/files/log/-->
<useAriaCrashHandler value="true"/>
<!--设置Aria的日志级别,{@link ALog#LOG_LEVEL_VERBOSE}-->
<logLevel value="2"/>
<!-- 是否检查网络 true: 检查网络,false: 不检查网络-->
<netCheck value="false"/>
<!--除非无法使用注解,否则不建议使用广播来接受任务状态,true:使用广播接收任务状态,false:不适用广播接收状态 -->
<!-- http://aria.laoyuyu.me/aria_doc/api/use_broadcast.html -->
<useBroadcast value="true"/>
<!--断网的时候是否重试,true:断网也重试;false:断网不重试,直接走失败的回调-->
<notNetRetry value="true"/>
</app>
<!--普通下载任务-->
<download>
<!--设置任务最大下载速度,0表示不限速,单位为:kb-->
<maxSpeed value="128"/>
<!--
多线程下载是否使用块下载模式,{@code true}使用,{@code false}不使用
注意:
1、使用分块模式,在读写性能底下的手机上,合并文件需要的时间会更加长;
2、优点是使用多线程的块下载,初始化时,文件初始化时将不会预占用对应长度的空间;
3、只对新的多线程下载任务有效
4、只对多线程的任务有效
-->
<useBlock value="true"/>
<!--设置下载线程数,下载线程数不能小于1
注意:
1、线程下载数改变后,新的下载任务才会生效;
2、如果任务大小小于1m,该设置不会生效;
3、从3.4.1开始,如果线程数为1,文件初始化时将不再预占用对应长度的空间,下载多少byte,则占多大的空间;
对于采用多线程的任务或旧任务,依然采用原来的文件空间占用方式;
-->
<threadNum value="3"/>
<!--设置下载队列最大任务数, 默认为2-->
<maxTaskNum value="1"/>
<!--设置下载失败,重试次数,默认为10-->
<reTryNum value="1"/>
<!--设置重试间隔,单位为毫秒,默认2000毫秒-->
<reTryInterval value="5000"/>
<!--设置url连接超时时间,单位为毫秒,默认5000毫秒-->
<connectTimeOut value="5000"/>
<!--设置IO流读取时间,单位为毫秒,默认20000毫秒,该时间不能少于10000毫秒-->
<iOTimeOut value="10000"/>
<!--设置写文件buff大小,该数值大小不能小于2048,数值变小,下载速度会变慢-->
<buffSize value="8192"/>
<!--设置https ca 证书信息;path 为assets目录下的CA证书完整路径,name 为CA证书名-->
<ca name="" path=""/>
<!--是否需要转换速度单位,转换完成后为:1b/s、1kb/s、1mb/s、1gb/s、1tb/s,如果不需要将返回byte长度-->
<convertSpeed value="true"/>
<!--执行队列类型,见com.arialyy.aria.core.QueueMod,默认类型为wait-->
<queueMod value="wait"/>
<!--进度更新更新间隔,默认1000毫秒-->
<updateInterval value="1000"/>
</download>
<!--普通上传任务-->
<upload>
<!--设置任务最大上传速度,0表示不限速,单位为:kb-->
<maxSpeed value="0"/>
<!--设置IO流读取时间,单位为毫秒,默认20000毫秒,该时间不能少于10000毫秒-->
<iOTimeOut value="10000"/>
<!--设置写文件buff大小,该数值大小不能小于2048,数值变小,速度会变慢-->
<buffSize value="8192"/>
<!--是否需要转换速度单位,转换完成后为:1b/s、1kb/s、1mb/s、1gb/s、1tb/s,如果不需要将返回byte长度-->
<convertSpeed value="true"/>
<!--设置上传队列最大任务数, 默认为2-->
<maxTaskNum value="2"/>
<!--设置上传失败,重试次数,默认为10-->
<reTryNum value="3"/>
<!--设置重试间隔,单位为毫秒-->
<reTryInterval value="2000"/>
<!--设置url连接超时时间,单位为毫秒,默认5000毫秒-->
<connectTimeOut value="5000"/>
<!--执行队列类型,见com.arialyy.aria.core.QueueMod,默认类型为wait-->
<queueMod value="wait"/>
<!--进度更新更新间隔,默认1000毫秒-->
<updateInterval value="1000"/>
</upload>
<!-- 下载类组合任务 -->
<dGroup>
<!--组合任务下载队列最大任务数, 默认为2-->
<maxTaskNum value="1"/>
<!--设置下载失败,重试次数,默认为10-->
<reTryNum value="1"/>
<!--设置重试间隔,单位为毫秒,默认2000毫秒-->
<reTryInterval value="5000"/>
<!--执行队列类型,见com.arialyy.aria.core.QueueMod,默认类型为wait-->
<queueMod value="wait"/>
<!--进度更新更新间隔,默认1000毫秒-->
<updateInterval value="1000"/>
<!-- =============================以下为子任务的配置====================================-->
<!--能同时下载的子任务最大任务数,默认3-->
<subMaxTaskNum value="1"/>
<!--子任务下载失败时的重试次数,默认为5-->
<subReTryNum value="5"/>
<!--子任务下载失败时的重试间隔,单位为毫秒,默认2000毫秒-->
<subReTryInterval value="5000"/>
<!--子任务url连接超时时间,单位为毫秒,默认5000毫秒-->
<connectTimeOut value="5000"/>
<!--子任务IO流读取时间,单位为毫秒,默认20000毫秒,该时间不能少于10000毫秒-->
<iOTimeOut value="10000"/>
<!--子任务写文件buff大小,该数值大小不能小于2048,数值变小,下载速度会变慢-->
<buffSize value="8192"/>
<!--子任务 https ca 证书信息;path 为assets目录下的CA证书完整路径,name 为CA证书名-->
<ca name="" path=""/>
<!--子任务是否需要转换速度单位,转换完成后为:1b/s、1kb/s、1mb/s、1gb/s、1tb/s,如果不需要将返回byte长度-->
<convertSpeed value="true"/>
<!--子任务的最大下载速度,0表示不限速,单位为:kb; -->
<maxSpeed value="0"/>
</dGroup>
<?xml version="1.0" encoding="utf-8"?>
<aria>
<!--注意,修改该配置文件中的属性会覆盖代码中所设置的属性-->
<!--Aria框架配置-->
<app>
<!--是否使用AriaCrashHandler来捕获异常,异常日志保存在:/mnt/sdcard/Android/data/{package_name}/files/log/-->
<useAriaCrashHandler value="true"/>
<!--设置Aria的日志级别,{@link ALog#LOG_LEVEL_VERBOSE}-->
<logLevel value="2"/>
<!-- 是否检查网络 true: 检查网络,false: 不检查网络-->
<netCheck value="false"/>
<!--除非无法使用注解,否则不建议使用广播来接受任务状态,true:使用广播接收任务状态,false:不适用广播接收状态 -->
<!-- http://aria.laoyuyu.me/aria_doc/api/use_broadcast.html -->
<useBroadcast value="true"/>
<!--断网的时候是否重试,true:断网也重试;false:断网不重试,直接走失败的回调-->
<notNetRetry value="true"/>
</app>
<!--普通下载任务-->
<download>
<!--设置任务最大下载速度,0表示不限速,单位为:kb-->
<maxSpeed value="128"/>
<!--
多线程下载是否使用块下载模式,{@code true}使用,{@code false}不使用
注意:
1、使用分块模式,在I/O性能底下的手机上,合并文件需要的时间会更加长;
2、优点是使用多线程的块下载,初始化时,文件初始化时将不会预占用对应长度的空间;
3、只对新的多线程下载任务有效
4、只对多线程的任务有效
-->
<useBlock value="true"/>
<!--设置下载线程数,下载线程数不能小于1
注意:
1、线程下载数改变后,新的下载任务才会生效;
2、如果任务大小小于1m,该设置不会生效;
3、从3.4.1开始,如果线程数为1,文件初始化时将不再预占用对应长度的空间,下载多少byte,则占多大的空间;
对于3.4.1之前版本的未完成的老任务,依然采用原来的文件空间占用方式;
-->
<threadNum value="1"/>
<!--设置下载队列最大任务数, 默认为2-->
<maxTaskNum value="1"/>
<!--设置下载失败,重试次数,默认为10-->
<reTryNum value="1"/>
<!--设置重试间隔,单位为毫秒,默认2000毫秒-->
<reTryInterval value="5000"/>
<!--设置url连接超时时间,单位为毫秒,默认5000毫秒-->
<connectTimeOut value="5000"/>
<!--设置IO流读取时间,单位为毫秒,默认20000毫秒,该时间不能少于10000毫秒-->
<iOTimeOut value="10000"/>
<!--设置写文件buff大小,该数值大小不能小于2048,数值变小,下载速度会变慢-->
<buffSize value="8192"/>
<!--设置https ca 证书信息;path 为assets目录下的CA证书完整路径,name 为CA证书名-->
<ca name="" path=""/>
<!--是否需要转换速度单位,转换完成后为:1b/s、1kb/s、1mb/s、1gb/s、1tb/s,如果不需要将返回byte长度-->
<convertSpeed value="true"/>
<!--执行队列类型,见com.arialyy.aria.core.QueueMod,默认类型为wait-->
<queueMod value="wait"/>
<!--进度更新更新间隔,默认1000毫秒-->
<updateInterval value="1000"/>
</download>
<!--普通上传任务-->
<upload>
<!--设置任务最大上传速度,0表示不限速,单位为:kb-->
<maxSpeed value="0"/>
<!--设置IO流读取时间,单位为毫秒,默认20000毫秒,该时间不能少于10000毫秒-->
<iOTimeOut value="10000"/>
<!--设置写文件buff大小,该数值大小不能小于2048,数值变小,速度会变慢-->
<buffSize value="8192"/>
<!--是否需要转换速度单位,转换完成后为:1b/s、1kb/s、1mb/s、1gb/s、1tb/s,如果不需要将返回byte长度-->
<convertSpeed value="true"/>
<!--设置上传队列最大任务数, 默认为2-->
<maxTaskNum value="2"/>
<!--设置上传失败,重试次数,默认为10-->
<reTryNum value="3"/>
<!--设置重试间隔,单位为毫秒-->
<reTryInterval value="2000"/>
<!--设置url连接超时时间,单位为毫秒,默认5000毫秒-->
<connectTimeOut value="5000"/>
<!--执行队列类型,见com.arialyy.aria.core.QueueMod,默认类型为wait-->
<queueMod value="wait"/>
<!--进度更新更新间隔,默认1000毫秒-->
<updateInterval value="1000"/>
</upload>
<!-- 下载类组合任务 -->
<dGroup>
<!--组合任务下载队列最大任务数, 默认为2-->
<maxTaskNum value="1"/>
<!--设置下载失败,重试次数,默认为10-->
<reTryNum value="1"/>
<!--设置重试间隔,单位为毫秒,默认2000毫秒-->
<reTryInterval value="5000"/>
<!--执行队列类型,见com.arialyy.aria.core.QueueMod,默认类型为wait-->
<queueMod value="wait"/>
<!--进度更新更新间隔,默认1000毫秒-->
<updateInterval value="1000"/>
<!-- =============================以下为子任务的配置====================================-->
<!--能同时下载的子任务最大任务数,默认3-->
<subMaxTaskNum value="1"/>
<!--子任务下载失败时的重试次数,默认为5-->
<subReTryNum value="5"/>
<!--子任务下载失败时的重试间隔,单位为毫秒,默认2000毫秒-->
<subReTryInterval value="5000"/>
<!--子任务url连接超时时间,单位为毫秒,默认5000毫秒-->
<connectTimeOut value="5000"/>
<!--子任务IO流读取时间,单位为毫秒,默认20000毫秒,该时间不能少于10000毫秒-->
<iOTimeOut value="10000"/>
<!--子任务写文件buff大小,该数值大小不能小于2048,数值变小,下载速度会变慢-->
<buffSize value="8192"/>
<!--子任务 https ca 证书信息;path 为assets目录下的CA证书完整路径,name 为CA证书名-->
<ca name="" path=""/>
<!--子任务是否需要转换速度单位,转换完成后为:1b/s、1kb/s、1mb/s、1gb/s、1tb/s,如果不需要将返回byte长度-->
<convertSpeed value="true"/>
<!--子任务的最大下载速度,0表示不限速,单位为:kb; -->
<maxSpeed value="0"/>
</dGroup>
</aria>

@ -35,9 +35,9 @@ import java.io.File;
* Ftp下载测试
*/
public class FtpDownloadActivity extends BaseActivity<ActivityFtpDownloadBinding> {
//private final String URL = "ftp://192.168.1.9:21/下载/AriaPrj.zip";
private final String URL = "ftp://9.9.9.205:2121/Cyberduck-6.9.4.30164.zip";
//private final String URL = "ftp://182.92.180.213:21/video/572fed5c2ad48_1024.jpg";
private final String URL = "ftp://182.92.180.213:21/DATA/20180205/rar/1111.rar";
//private final String URL = "ftp://182.92.180.213:21/DATA/20180205/rar/1111.rar";
//private final String URL = "ftp://d:d@dygodj8.com:12311/咖啡风暴HD大陆公映意语中字[飘花www.piaohua.com].mp4";
@Override protected void init(Bundle savedInstanceState) {

@ -147,7 +147,7 @@ public class HighestPriorityActivity extends BaseActivity<ActivityHighestPriorit
if (text.equals("重新开始?") || text.equals("开始")) {
Aria.download(this)
.load(DOWNLOAD_URL)
.setDownloadPath(Environment.getExternalStorageDirectory().getPath()
.setFilePath(Environment.getExternalStorageDirectory().getPath()
+ "/Download/"
+ mTaskName
+ ".apk")

@ -312,23 +312,10 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
int i = 1;
private void startD() {
//Aria.get(this).setLogLevel(ALog.LOG_CLOSE);
//Aria.download(this).load("aaaa.apk");
String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/ggsg11.mp4";
//String path = String.format("/sdcard/ggsg11(%s).mp4", i);
//if (new File(path).exists()) {
//
// i++;
// path = String.format("/sdcard/ggsg11(%s).mp4", i);
//}
//File file = new File(path);
//if (file.exists()){
// file.delete();
//}
//Aria.download(SingleTaskActivity.this).load(DOWNLOAD_URL).resetState().save();
Map<String, String> params = new HashMap<>();
params.put("key", "value");
params.put("filename", "CentOS-7-x86_64-Minimal-1804.iso");
String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/ggsg14.apk";
//Map<String, String> params = new HashMap<>();
//params.put("key", "value");
//params.put("filename", "CentOS-7-x86_64-Minimal-1804.iso");
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")

@ -1,80 +1,80 @@
package com.arialyy.simple.core.test;
import android.os.Environment;
import android.view.View;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.common.QueueMod;
import com.arialyy.simple.R;
import com.arialyy.simple.base.BaseActivity;
import com.arialyy.simple.databinding.TestActivityMultiBinding;
/**
* Created by AriaL on 2017/6/15.
*/
public class TestMutilTaskSysDownload extends BaseActivity<TestActivityMultiBinding> {
@Override protected int setLayoutId() {
return R.layout.test_activity_multi;
}
public void onClick(View view) {
String baseUrl = "http://file.bmob.cn/";
String[] urlArray = {
"M02/3B/A4/oYYBAFaOeUSAc1QiAAFTbmA7AHs052.jpg",
"M02/3B/A4/oYYBAFaOeUaAfYC-AAFD8zf9NXc879.jpg",
"M02/3B/A4/oYYBAFaOeUuAOxhnAACSdmbqSac702.jpg",
"M02/3B/A4/oYYBAFaOeU2AFAIGAAFICximvXc924.jpg",
"M02/3B/A4/oYYBAFaOeVCAPWMQAAFm2KWCq_E721.jpg",
"M02/3B/A4/oYYBAFaOeVOAbiv9AAFfCTTgr94948.jpg",
"M02/3B/A4/oYYBAFaOeVaAMR3tAAFf3yTuuCM577.jpg",
"M02/3B/A4/oYYBAFaOeVmACEWhAAEt72ecbpg468.jpg",
"M02/3B/A4/oYYBAFaOeVyAHHt4AAFg9e9bRio507.jpg",
"M02/3B/A4/oYYBAFaOeV-AClYXAAESLGY0gag424.jpg",
"M02/3B/A4/oYYBAFaOeWKAA7N0AAF3omYOJUI703.jpg",
"M02/3B/A4/oYYBAFaOeWWAD2lrAAFN7eRFxBs575.jpg",
"M02/3B/A4/oYYBAFaOeWiAdCVEAAFg4273Dus313.jpg",
"M02/3B/A4/oYYBAFaOeWyAJDm5AAF8JVoGVb0705.jpg",
"M02/3B/A4/oYYBAFaOeW-AUoA8AAGjKiHkXUo181.jpg",
"M02/3B/A4/oYYBAFaOeXKABIamAAFU7J7vraE265.jpg",
"M02/3B/A5/oYYBAFaOeXaAW09jAAFf37qdwDA457.jpg",
"M02/3B/A5/oYYBAFaOeXmAWmS7AAFtLNpWjgo967.jpg",
"M02/3B/A5/oYYBAFaOeX2AQf9cAAF2fhwS2UE145.jpg",
"M02/3B/A5/oYYBAFaOeYCAKGnLAAFVAzks-qU937.jpg",
"M02/3B/A5/oYYBAFaOeYOAMODNAAF6HjTTMq4819.jpg",
"M02/3B/A5/oYYBAFaOeYeAbn8uAAFLSQLw48Q042.jpg",
"M02/3B/A5/oYYBAFaOeYqAMJThAAFtrNe4UNM047.jpg",
"M02/3B/A5/oYYBAFaOeY2AbnQvAAFNSXWn0Dc026.jpg",
"M02/3B/A5/oYYBAFaOeZCAIsr0AAFHZFEVhPc682.jpg",
"M02/3B/A5/oYYBAFaOeZOAGvITAAFqPmfcc9c471.jpg",
"M02/3B/A5/oYYBAFaOeZaATvjbAAFHDmALnhE003.jpg",
"M02/3B/A5/oYYBAFaOeZmAJPuVAAFfPJC2wsE319.jpg",
"M02/3B/A5/oYYBAFaOeZyAXtAmAAFfArJNwtM371.jpg",
"M02/3B/A5/oYYBAFaOeZ-AGZN0AAFgqwYYCS8004.jpg",
"M02/3B/A5/oYYBAFaOeaOAbbrGAAFcq59JjUo205.jpg",
"M02/3B/A5/oYYBAFaOeaSAdFyoAACaxVxgUJA092.jpg"
};
int maxNum = Aria.get(this).getDownloadConfig().getMaxTaskNum();
Aria.get(this).setDownloadQueueMod(QueueMod.NOW);
for (int i = 0; i < urlArray.length; i++) {
Aria.download(this)
.load(baseUrl + urlArray[i])
.setDownloadPath(Environment.getExternalStorageDirectory() + "/test/" + i + ".jpg")
//.addHeader("Accept-Encoding", "gzip,deflate,sdcn")
.start();
//if (i < maxNum) {
// Aria.download(this)
// .load(baseUrl + urlArray[i])
// .setDownloadPath(Environment.getExternalStorageDirectory() + "/test/" + i + ".jpg")
// //.addHeader("Accept-Encoding", "gzip,deflate,sdcn")
// .start();
//} else {
// Aria.download(this)
// .load(baseUrl + urlArray[i])
// .setDownloadPath(Environment.getExternalStorageDirectory() + "/test/" + i + ".jpg")
// //.addHeader("Accept-Encoding", "gzip,deflate,sdcn")
// .add();
//}
}
}
}
package com.arialyy.simple.core.test;
import android.os.Environment;
import android.view.View;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.common.QueueMod;
import com.arialyy.simple.R;
import com.arialyy.simple.base.BaseActivity;
import com.arialyy.simple.databinding.TestActivityMultiBinding;
/**
* Created by AriaL on 2017/6/15.
*/
public class TestMutilTaskSysDownload extends BaseActivity<TestActivityMultiBinding> {
@Override protected int setLayoutId() {
return R.layout.test_activity_multi;
}
public void onClick(View view) {
String baseUrl = "http://file.bmob.cn/";
String[] urlArray = {
"M02/3B/A4/oYYBAFaOeUSAc1QiAAFTbmA7AHs052.jpg",
"M02/3B/A4/oYYBAFaOeUaAfYC-AAFD8zf9NXc879.jpg",
"M02/3B/A4/oYYBAFaOeUuAOxhnAACSdmbqSac702.jpg",
"M02/3B/A4/oYYBAFaOeU2AFAIGAAFICximvXc924.jpg",
"M02/3B/A4/oYYBAFaOeVCAPWMQAAFm2KWCq_E721.jpg",
"M02/3B/A4/oYYBAFaOeVOAbiv9AAFfCTTgr94948.jpg",
"M02/3B/A4/oYYBAFaOeVaAMR3tAAFf3yTuuCM577.jpg",
"M02/3B/A4/oYYBAFaOeVmACEWhAAEt72ecbpg468.jpg",
"M02/3B/A4/oYYBAFaOeVyAHHt4AAFg9e9bRio507.jpg",
"M02/3B/A4/oYYBAFaOeV-AClYXAAESLGY0gag424.jpg",
"M02/3B/A4/oYYBAFaOeWKAA7N0AAF3omYOJUI703.jpg",
"M02/3B/A4/oYYBAFaOeWWAD2lrAAFN7eRFxBs575.jpg",
"M02/3B/A4/oYYBAFaOeWiAdCVEAAFg4273Dus313.jpg",
"M02/3B/A4/oYYBAFaOeWyAJDm5AAF8JVoGVb0705.jpg",
"M02/3B/A4/oYYBAFaOeW-AUoA8AAGjKiHkXUo181.jpg",
"M02/3B/A4/oYYBAFaOeXKABIamAAFU7J7vraE265.jpg",
"M02/3B/A5/oYYBAFaOeXaAW09jAAFf37qdwDA457.jpg",
"M02/3B/A5/oYYBAFaOeXmAWmS7AAFtLNpWjgo967.jpg",
"M02/3B/A5/oYYBAFaOeX2AQf9cAAF2fhwS2UE145.jpg",
"M02/3B/A5/oYYBAFaOeYCAKGnLAAFVAzks-qU937.jpg",
"M02/3B/A5/oYYBAFaOeYOAMODNAAF6HjTTMq4819.jpg",
"M02/3B/A5/oYYBAFaOeYeAbn8uAAFLSQLw48Q042.jpg",
"M02/3B/A5/oYYBAFaOeYqAMJThAAFtrNe4UNM047.jpg",
"M02/3B/A5/oYYBAFaOeY2AbnQvAAFNSXWn0Dc026.jpg",
"M02/3B/A5/oYYBAFaOeZCAIsr0AAFHZFEVhPc682.jpg",
"M02/3B/A5/oYYBAFaOeZOAGvITAAFqPmfcc9c471.jpg",
"M02/3B/A5/oYYBAFaOeZaATvjbAAFHDmALnhE003.jpg",
"M02/3B/A5/oYYBAFaOeZmAJPuVAAFfPJC2wsE319.jpg",
"M02/3B/A5/oYYBAFaOeZyAXtAmAAFfArJNwtM371.jpg",
"M02/3B/A5/oYYBAFaOeZ-AGZN0AAFgqwYYCS8004.jpg",
"M02/3B/A5/oYYBAFaOeaOAbbrGAAFcq59JjUo205.jpg",
"M02/3B/A5/oYYBAFaOeaSAdFyoAACaxVxgUJA092.jpg"
};
int maxNum = Aria.get(this).getDownloadConfig().getMaxTaskNum();
Aria.get(this).setDownloadQueueMod(QueueMod.NOW);
for (int i = 0; i < urlArray.length; i++) {
Aria.download(this)
.load(baseUrl + urlArray[i])
.setFilePath(Environment.getExternalStorageDirectory() + "/test/" + i + ".jpg")
//.addHeader("Accept-Encoding", "gzip,deflate,sdcn")
.start();
//if (i < maxNum) {
// Aria.download(this)
// .load(baseUrl + urlArray[i])
// .setDownloadPath(Environment.getExternalStorageDirectory() + "/test/" + i + ".jpg")
// //.addHeader("Accept-Encoding", "gzip,deflate,sdcn")
// .start();
//} else {
// Aria.download(this)
// .load(baseUrl + urlArray[i])
// .setDownloadPath(Environment.getExternalStorageDirectory() + "/test/" + i + ".jpg")
// //.addHeader("Accept-Encoding", "gzip,deflate,sdcn")
// .add();
//}
}
}
}

@ -1,113 +1,113 @@
/*
* 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.simple.core.upload;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import com.arialyy.annotations.Upload;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.core.upload.UploadTask;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.frame.util.FileUtil;
import com.arialyy.frame.util.show.T;
import com.arialyy.simple.R;
import com.arialyy.simple.base.BaseActivity;
import com.arialyy.simple.databinding.ActivityFtpUploadBinding;
import java.io.File;
/**
* Created by lyy on 2017/7/28. Ftp 文件上传demo
*/
public class FtpUploadActivity extends BaseActivity<ActivityFtpUploadBinding> {
private final String FILE_PATH = "/mnt/sdcard/AriaPrj.rar";
private final String URL = "ftp://9.9.9.50:21/aa/你好";
@Override protected void init(Bundle savedInstanceState) {
setTile("D_FTP 文件上传");
super.init(savedInstanceState);
Aria.upload(this).register();
UploadEntity entity = Aria.upload(this).getUploadEntity(FILE_PATH);
if (entity != null) {
getBinding().setFileSize(CommonUtil.formatFileSize(entity.getFileSize()));
getBinding().setProgress(entity.isComplete() ? 100
: (int) (entity.getCurrentProgress() * 100 / entity.getFileSize()));
}
}
@Override protected int setLayoutId() {
return R.layout.activity_ftp_upload;
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.start:
Aria.upload(this).loadFtp(FILE_PATH).setUploadUrl(URL).login("lao", "123456").start();
break;
case R.id.stop:
Aria.upload(this).loadFtp(FILE_PATH).stop();
break;
case R.id.cancel:
Aria.upload(this).loadFtp(FILE_PATH).cancel();
break;
}
}
@Upload.onWait void onWait(UploadTask task) {
Log.d(TAG, task.getTaskName() + "_wait");
}
@Upload.onPre public void onPre(UploadTask task) {
getBinding().setFileSize(task.getConvertFileSize());
}
@Upload.onTaskStart public void taskStart(UploadTask task) {
Log.d(TAG, "开始上传,md5:" + FileUtil.getFileMD5(new File(task.getEntity().getFilePath())));
}
@Upload.onTaskResume public void taskResume(UploadTask task) {
Log.d(TAG, "恢复上传");
}
@Upload.onTaskStop public void taskStop(UploadTask task) {
getBinding().setSpeed("");
Log.d(TAG, "停止上传");
}
@Upload.onTaskCancel public void taskCancel(UploadTask task) {
getBinding().setSpeed("");
getBinding().setFileSize("");
getBinding().setProgress(0);
Log.d(TAG, "删除任务");
}
@Upload.onTaskFail public void taskFail(UploadTask task) {
Log.d(TAG, "上传失败");
}
@Upload.onTaskRunning public void taskRunning(UploadTask task) {
Log.d(TAG, "PP = " + task.getPercent());
getBinding().setProgress(task.getPercent());
getBinding().setSpeed(task.getConvertSpeed());
}
@Upload.onTaskComplete public void taskComplete(UploadTask task) {
getBinding().setProgress(100);
getBinding().setSpeed("");
T.showShort(this, "文件:" + task.getEntity().getFileName() + ",上传完成");
}
}
/*
* 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.simple.core.upload;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import com.arialyy.annotations.Upload;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.core.upload.UploadTask;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.frame.util.FileUtil;
import com.arialyy.frame.util.show.T;
import com.arialyy.simple.R;
import com.arialyy.simple.base.BaseActivity;
import com.arialyy.simple.databinding.ActivityFtpUploadBinding;
import java.io.File;
/**
* Created by lyy on 2017/7/28. Ftp 文件上传demo
*/
public class FtpUploadActivity extends BaseActivity<ActivityFtpUploadBinding> {
private final String FILE_PATH = "/mnt/sdcard/AriaPrj.rar";
private final String URL = "ftp://9.9.9.205:2121/aa/你好";
@Override protected void init(Bundle savedInstanceState) {
setTile("D_FTP 文件上传");
super.init(savedInstanceState);
Aria.upload(this).register();
UploadEntity entity = Aria.upload(this).getUploadEntity(FILE_PATH);
if (entity != null) {
getBinding().setFileSize(CommonUtil.formatFileSize(entity.getFileSize()));
getBinding().setProgress(entity.isComplete() ? 100
: (int) (entity.getCurrentProgress() * 100 / entity.getFileSize()));
}
}
@Override protected int setLayoutId() {
return R.layout.activity_ftp_upload;
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.start:
Aria.upload(this).loadFtp(FILE_PATH).setUploadUrl(URL).login("lao", "123456").start();
break;
case R.id.stop:
Aria.upload(this).loadFtp(FILE_PATH).stop();
break;
case R.id.cancel:
Aria.upload(this).loadFtp(FILE_PATH).cancel();
break;
}
}
@Upload.onWait void onWait(UploadTask task) {
Log.d(TAG, task.getTaskName() + "_wait");
}
@Upload.onPre public void onPre(UploadTask task) {
getBinding().setFileSize(task.getConvertFileSize());
}
@Upload.onTaskStart public void taskStart(UploadTask task) {
Log.d(TAG, "开始上传,md5:" + FileUtil.getFileMD5(new File(task.getEntity().getFilePath())));
}
@Upload.onTaskResume public void taskResume(UploadTask task) {
Log.d(TAG, "恢复上传");
}
@Upload.onTaskStop public void taskStop(UploadTask task) {
getBinding().setSpeed("");
Log.d(TAG, "停止上传");
}
@Upload.onTaskCancel public void taskCancel(UploadTask task) {
getBinding().setSpeed("");
getBinding().setFileSize("");
getBinding().setProgress(0);
Log.d(TAG, "删除任务");
}
@Upload.onTaskFail public void taskFail(UploadTask task) {
Log.d(TAG, "上传失败");
}
@Upload.onTaskRunning public void taskRunning(UploadTask task) {
Log.d(TAG, "PP = " + task.getPercent());
getBinding().setProgress(task.getPercent());
getBinding().setSpeed(task.getConvertSpeed());
}
@Upload.onTaskComplete public void taskComplete(UploadTask task) {
getBinding().setProgress(100);
getBinding().setSpeed("");
T.showShort(this, "文件:" + task.getEntity().getFileName() + ",上传完成");
}
}

Loading…
Cancel
Save