优化AbsThreadTask代码, 新增文件长度处理功能 https://github.com/AriaLyy/Aria/issues/393
parent
0c3e16cad7
commit
0dbc515cd3
@ -1,104 +1,103 @@ |
||||
/* |
||||
* 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.http; |
||||
|
||||
import android.text.TextUtils; |
||||
import com.arialyy.aria.core.download.DGTaskWrapper; |
||||
import com.arialyy.aria.core.download.DTaskWrapper; |
||||
import com.arialyy.aria.core.download.DownloadGroupTarget; |
||||
import com.arialyy.aria.core.inf.AbsTarget; |
||||
import com.arialyy.aria.core.inf.ITargetHandler; |
||||
import com.arialyy.aria.util.ALog; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* HTTP参数委托 |
||||
* @param <TARGET> |
||||
*/ |
||||
class HttpDelegate<TARGET extends AbsTarget> implements ITargetHandler { |
||||
private static final String TAG = "PostDelegate"; |
||||
TARGET mTarget; |
||||
|
||||
HttpDelegate(TARGET target) { |
||||
mTarget = target; |
||||
} |
||||
|
||||
public TARGET setParams(Map<String, String> params) { |
||||
mTarget.getTaskWrapper().asHttp().setParams(params); |
||||
if (mTarget instanceof DownloadGroupTarget) { |
||||
for (DTaskWrapper subTask : ((DGTaskWrapper) mTarget.getTaskWrapper()).getSubTaskWrapper()) { |
||||
subTask.asHttp().setParams(params); |
||||
} |
||||
} |
||||
return mTarget; |
||||
} |
||||
|
||||
public TARGET setParam(String key, String value) { |
||||
if (TextUtils.isEmpty(key) || TextUtils.isEmpty(value)) { |
||||
ALog.d(TAG, "key 或value 为空"); |
||||
return mTarget; |
||||
} |
||||
Map<String, String> params = mTarget.getTaskWrapper().asHttp().getParams(); |
||||
if (params == null) { |
||||
params = new HashMap<>(); |
||||
mTarget.getTaskWrapper().asHttp().setParams(params); |
||||
} |
||||
params.put(key, value); |
||||
if (mTarget instanceof DownloadGroupTarget) { |
||||
for (DTaskWrapper subTask : ((DGTaskWrapper) mTarget.getTaskWrapper()).getSubTaskWrapper()) { |
||||
subTask.asHttp().setParams(params); |
||||
} |
||||
} |
||||
return mTarget; |
||||
} |
||||
|
||||
@Override public void add() { |
||||
mTarget.add(); |
||||
} |
||||
|
||||
@Override public void start() { |
||||
mTarget.start(); |
||||
} |
||||
|
||||
@Override public void stop() { |
||||
mTarget.stop(); |
||||
} |
||||
|
||||
@Override public void resume() { |
||||
mTarget.resume(); |
||||
} |
||||
|
||||
@Override public void cancel() { |
||||
mTarget.cancel(); |
||||
} |
||||
|
||||
@Override public void save() { |
||||
mTarget.save(); |
||||
} |
||||
|
||||
@Override public void cancel(boolean removeFile) { |
||||
mTarget.cancel(removeFile); |
||||
} |
||||
|
||||
@Override public void reTry() { |
||||
mTarget.reTry(); |
||||
} |
||||
|
||||
@Override public void reStart() { |
||||
mTarget.reStart(); |
||||
} |
||||
} |
||||
/* |
||||
* 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.http; |
||||
|
||||
import android.text.TextUtils; |
||||
import com.arialyy.aria.core.download.DGTaskWrapper; |
||||
import com.arialyy.aria.core.download.DTaskWrapper; |
||||
import com.arialyy.aria.core.download.DownloadGroupTarget; |
||||
import com.arialyy.aria.core.inf.AbsTarget; |
||||
import com.arialyy.aria.core.inf.ITargetHandler; |
||||
import com.arialyy.aria.util.ALog; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* HTTP参数委托 |
||||
*/ |
||||
class HttpDelegate<TARGET extends AbsTarget> implements ITargetHandler { |
||||
private static final String TAG = "PostDelegate"; |
||||
TARGET mTarget; |
||||
|
||||
HttpDelegate(TARGET target) { |
||||
mTarget = target; |
||||
} |
||||
|
||||
public TARGET setParams(Map<String, String> params) { |
||||
mTarget.getTaskWrapper().asHttp().setParams(params); |
||||
if (mTarget instanceof DownloadGroupTarget) { |
||||
for (DTaskWrapper subTask : ((DGTaskWrapper) mTarget.getTaskWrapper()).getSubTaskWrapper()) { |
||||
subTask.asHttp().setParams(params); |
||||
} |
||||
} |
||||
return mTarget; |
||||
} |
||||
|
||||
public TARGET setParam(String key, String value) { |
||||
if (TextUtils.isEmpty(key) || TextUtils.isEmpty(value)) { |
||||
ALog.d(TAG, "key 或value 为空"); |
||||
return mTarget; |
||||
} |
||||
Map<String, String> params = mTarget.getTaskWrapper().asHttp().getParams(); |
||||
if (params == null) { |
||||
params = new HashMap<>(); |
||||
mTarget.getTaskWrapper().asHttp().setParams(params); |
||||
} |
||||
params.put(key, value); |
||||
if (mTarget instanceof DownloadGroupTarget) { |
||||
for (DTaskWrapper subTask : ((DGTaskWrapper) mTarget.getTaskWrapper()).getSubTaskWrapper()) { |
||||
subTask.asHttp().setParams(params); |
||||
} |
||||
} |
||||
return mTarget; |
||||
} |
||||
|
||||
@Override public void add() { |
||||
mTarget.add(); |
||||
} |
||||
|
||||
@Override public void start() { |
||||
mTarget.start(); |
||||
} |
||||
|
||||
@Override public void stop() { |
||||
mTarget.stop(); |
||||
} |
||||
|
||||
@Override public void resume() { |
||||
mTarget.resume(); |
||||
} |
||||
|
||||
@Override public void cancel() { |
||||
mTarget.cancel(); |
||||
} |
||||
|
||||
@Override public void save() { |
||||
mTarget.save(); |
||||
} |
||||
|
||||
@Override public void cancel(boolean removeFile) { |
||||
mTarget.cancel(removeFile); |
||||
} |
||||
|
||||
@Override public void reTry() { |
||||
mTarget.reTry(); |
||||
} |
||||
|
||||
@Override public void reStart() { |
||||
mTarget.reStart(); |
||||
} |
||||
} |
||||
|
@ -1,187 +1,198 @@ |
||||
/* |
||||
* 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.http; |
||||
|
||||
import com.arialyy.aria.core.common.RequestEnum; |
||||
import com.arialyy.aria.core.inf.ITargetHeadDelegate; |
||||
import java.net.CookieManager; |
||||
import java.net.Proxy; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* Http任务设置的信息,如:cookie、请求参数 |
||||
*/ |
||||
public class HttpTaskDelegate implements ITargetHeadDelegate { |
||||
|
||||
private CookieManager cookieManager; |
||||
|
||||
/** |
||||
* 请求参数 |
||||
*/ |
||||
private Map<String, String> params; |
||||
|
||||
/** |
||||
* http 请求头 |
||||
*/ |
||||
private Map<String, String> headers = new HashMap<>(); |
||||
|
||||
/** |
||||
* 字符编码,默认为"utf-8" |
||||
*/ |
||||
private String charSet = "utf-8"; |
||||
|
||||
/** |
||||
* 网络请求类型 |
||||
*/ |
||||
private RequestEnum requestEnum = RequestEnum.GET; |
||||
|
||||
/** |
||||
* 是否使用服务器通过content-disposition传递的文件名,内容格式{@code attachment; filename="filename.jpg"} {@code true} |
||||
* 使用 |
||||
*/ |
||||
private boolean useServerFileName = false; |
||||
|
||||
/** |
||||
* 重定向链接 |
||||
*/ |
||||
private String redirectUrl = ""; |
||||
|
||||
/** |
||||
* 是否是chunk模式 |
||||
*/ |
||||
private boolean isChunked = false; |
||||
/** |
||||
* 文件上传需要的key |
||||
*/ |
||||
private String attachment; |
||||
/** |
||||
* 上传的文件类型 |
||||
*/ |
||||
private String contentType = "multipart/form-data"; |
||||
private String userAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)"; |
||||
|
||||
private Proxy proxy; |
||||
/** |
||||
* 文件上传表单 |
||||
*/ |
||||
private Map<String, String> formFields = new HashMap<>(); |
||||
|
||||
public Map<String, String> getFormFields() { |
||||
return formFields; |
||||
} |
||||
|
||||
public void setFormFields(Map<String, String> formFields) { |
||||
this.formFields = formFields; |
||||
} |
||||
|
||||
public String getAttachment() { |
||||
return attachment; |
||||
} |
||||
|
||||
public void setAttachment(String attachment) { |
||||
this.attachment = attachment; |
||||
} |
||||
|
||||
public String getContentType() { |
||||
return contentType; |
||||
} |
||||
|
||||
public void setContentType(String contentType) { |
||||
this.contentType = contentType; |
||||
} |
||||
|
||||
public String getUserAgent() { |
||||
return userAgent; |
||||
} |
||||
|
||||
public void setUserAgent(String userAgent) { |
||||
this.userAgent = userAgent; |
||||
} |
||||
|
||||
public boolean isChunked() { |
||||
return isChunked; |
||||
} |
||||
|
||||
public void setChunked(boolean chunked) { |
||||
isChunked = chunked; |
||||
} |
||||
|
||||
public CookieManager getCookieManager() { |
||||
return cookieManager; |
||||
} |
||||
|
||||
public void setCookieManager(CookieManager cookieManager) { |
||||
this.cookieManager = cookieManager; |
||||
} |
||||
|
||||
public Proxy getProxy() { |
||||
return proxy; |
||||
} |
||||
|
||||
public void setProxy(Proxy proxy) { |
||||
this.proxy = proxy; |
||||
} |
||||
|
||||
public Map<String, String> getHeaders() { |
||||
return headers; |
||||
} |
||||
|
||||
public void setHeaders(Map<String, String> headers) { |
||||
this.headers = headers; |
||||
} |
||||
|
||||
public String getCharSet() { |
||||
return charSet; |
||||
} |
||||
|
||||
public void setCharSet(String charSet) { |
||||
this.charSet = charSet; |
||||
} |
||||
|
||||
public RequestEnum getRequestEnum() { |
||||
return requestEnum; |
||||
} |
||||
|
||||
public void setRequestEnum(RequestEnum requestEnum) { |
||||
this.requestEnum = requestEnum; |
||||
} |
||||
|
||||
public boolean isUseServerFileName() { |
||||
return useServerFileName; |
||||
} |
||||
|
||||
public void setUseServerFileName(boolean useServerFileName) { |
||||
this.useServerFileName = useServerFileName; |
||||
} |
||||
|
||||
public String getRedirectUrl() { |
||||
return redirectUrl; |
||||
} |
||||
|
||||
public void setRedirectUrl(String redirectUrl) { |
||||
this.redirectUrl = redirectUrl; |
||||
} |
||||
|
||||
public Map<String, String> getParams() { |
||||
return params; |
||||
} |
||||
|
||||
public void setParams(Map<String, String> params) { |
||||
this.params = params; |
||||
} |
||||
} |
||||
/* |
||||
* 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.http; |
||||
|
||||
import com.arialyy.aria.core.common.RequestEnum; |
||||
import com.arialyy.aria.core.inf.IHttpFileLenAdapter; |
||||
import com.arialyy.aria.core.inf.ITargetHeadDelegate; |
||||
import java.net.CookieManager; |
||||
import java.net.Proxy; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* Http任务设置的信息,如:cookie、请求参数 |
||||
*/ |
||||
public class HttpTaskDelegate implements ITargetHeadDelegate { |
||||
|
||||
private CookieManager cookieManager; |
||||
|
||||
/** |
||||
* 请求参数 |
||||
*/ |
||||
private Map<String, String> params; |
||||
|
||||
/** |
||||
* http 请求头 |
||||
*/ |
||||
private Map<String, String> headers = new HashMap<>(); |
||||
|
||||
/** |
||||
* 字符编码,默认为"utf-8" |
||||
*/ |
||||
private String charSet = "utf-8"; |
||||
|
||||
/** |
||||
* 网络请求类型 |
||||
*/ |
||||
private RequestEnum requestEnum = RequestEnum.GET; |
||||
|
||||
/** |
||||
* 是否使用服务器通过content-disposition传递的文件名,内容格式{@code attachment; filename="filename.jpg"} {@code true} |
||||
* 使用 |
||||
*/ |
||||
private boolean useServerFileName = false; |
||||
|
||||
/** |
||||
* 重定向链接 |
||||
*/ |
||||
private String redirectUrl = ""; |
||||
|
||||
/** |
||||
* 是否是chunk模式 |
||||
*/ |
||||
private boolean isChunked = false; |
||||
/** |
||||
* 文件上传需要的key |
||||
*/ |
||||
private String attachment; |
||||
/** |
||||
* 上传的文件类型 |
||||
*/ |
||||
private String contentType = "multipart/form-data"; |
||||
private String userAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)"; |
||||
|
||||
private Proxy proxy; |
||||
/** |
||||
* 文件上传表单 |
||||
*/ |
||||
private Map<String, String> formFields = new HashMap<>(); |
||||
|
||||
private IHttpFileLenAdapter fileLenAdapter; |
||||
|
||||
public IHttpFileLenAdapter getFileLenAdapter() { |
||||
return fileLenAdapter; |
||||
} |
||||
|
||||
public void setFileLenAdapter(IHttpFileLenAdapter fileLenAdapter) { |
||||
this.fileLenAdapter = fileLenAdapter; |
||||
} |
||||
|
||||
public Map<String, String> getFormFields() { |
||||
return formFields; |
||||
} |
||||
|
||||
public void setFormFields(Map<String, String> formFields) { |
||||
this.formFields = formFields; |
||||
} |
||||
|
||||
public String getAttachment() { |
||||
return attachment; |
||||
} |
||||
|
||||
public void setAttachment(String attachment) { |
||||
this.attachment = attachment; |
||||
} |
||||
|
||||
public String getContentType() { |
||||
return contentType; |
||||
} |
||||
|
||||
public void setContentType(String contentType) { |
||||
this.contentType = contentType; |
||||
} |
||||
|
||||
public String getUserAgent() { |
||||
return userAgent; |
||||
} |
||||
|
||||
public void setUserAgent(String userAgent) { |
||||
this.userAgent = userAgent; |
||||
} |
||||
|
||||
public boolean isChunked() { |
||||
return isChunked; |
||||
} |
||||
|
||||
public void setChunked(boolean chunked) { |
||||
isChunked = chunked; |
||||
} |
||||
|
||||
public CookieManager getCookieManager() { |
||||
return cookieManager; |
||||
} |
||||
|
||||
public void setCookieManager(CookieManager cookieManager) { |
||||
this.cookieManager = cookieManager; |
||||
} |
||||
|
||||
public Proxy getProxy() { |
||||
return proxy; |
||||
} |
||||
|
||||
public void setProxy(Proxy proxy) { |
||||
this.proxy = proxy; |
||||
} |
||||
|
||||
public Map<String, String> getHeaders() { |
||||
return headers; |
||||
} |
||||
|
||||
public void setHeaders(Map<String, String> headers) { |
||||
this.headers = headers; |
||||
} |
||||
|
||||
public String getCharSet() { |
||||
return charSet; |
||||
} |
||||
|
||||
public void setCharSet(String charSet) { |
||||
this.charSet = charSet; |
||||
} |
||||
|
||||
public RequestEnum getRequestEnum() { |
||||
return requestEnum; |
||||
} |
||||
|
||||
public void setRequestEnum(RequestEnum requestEnum) { |
||||
this.requestEnum = requestEnum; |
||||
} |
||||
|
||||
public boolean isUseServerFileName() { |
||||
return useServerFileName; |
||||
} |
||||
|
||||
public void setUseServerFileName(boolean useServerFileName) { |
||||
this.useServerFileName = useServerFileName; |
||||
} |
||||
|
||||
public String getRedirectUrl() { |
||||
return redirectUrl; |
||||
} |
||||
|
||||
public void setRedirectUrl(String redirectUrl) { |
||||
this.redirectUrl = redirectUrl; |
||||
} |
||||
|
||||
public Map<String, String> getParams() { |
||||
return params; |
||||
} |
||||
|
||||
public void setParams(Map<String, String> params) { |
||||
this.params = params; |
||||
} |
||||
} |
||||
|
@ -1,171 +1,68 @@ |
||||
/* |
||||
* 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.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; |
||||
import com.arialyy.aria.util.ALog; |
||||
import java.io.File; |
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* Created by lyy on 2017/7/26. |
||||
*/ |
||||
abstract class AbsDGTarget<TARGET extends AbsDGTarget> extends AbsTarget<TARGET> { |
||||
|
||||
///**
|
||||
// * 组任务名
|
||||
// */
|
||||
//String mGroupHash;
|
||||
///**
|
||||
// * 文件夹临时路径
|
||||
// */
|
||||
//String mDirPathTemp;
|
||||
///**
|
||||
// * 是否需要修改路径
|
||||
// */
|
||||
//boolean needModifyPath = false;
|
||||
|
||||
private SubTaskManager mSubTaskManager; |
||||
|
||||
/** |
||||
* 获取子任务管理器 |
||||
* |
||||
* @return 子任务管理器 |
||||
*/ |
||||
@CheckResult |
||||
public SubTaskManager getSubTaskManager() { |
||||
if (mSubTaskManager == null) { |
||||
mSubTaskManager = new SubTaskManager(getTargetName(), getTaskWrapper()); |
||||
} |
||||
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; |
||||
getEntity().setAlias(alias); |
||||
return (TARGET) this; |
||||
} |
||||
|
||||
//@Override public boolean taskExists() {
|
||||
// return DbEntity.checkDataExist(DownloadGroupEntity.class, "groupHash=?", mGroupHash);
|
||||
//}
|
||||
|
||||
///**
|
||||
// * 设置任务组的文件夹路径,在Aria中,任务组的所有子任务都会下载到以任务组组名的文件夹中。
|
||||
// * 如:groupDirPath = "/mnt/sdcard/download/group_test"
|
||||
// * <pre>
|
||||
// * {@code
|
||||
// * + mnt
|
||||
// * + sdcard
|
||||
// * + download
|
||||
// * + group_test
|
||||
// * - task1.apk
|
||||
// * - task2.apk
|
||||
// * - task3.apk
|
||||
// * ....
|
||||
// *
|
||||
// * }
|
||||
// * </pre>
|
||||
// *
|
||||
// * @param dirPath 任务组保存文件夹路径
|
||||
// */
|
||||
//@CheckResult
|
||||
//public TARGET setDirPath(String dirPath) {
|
||||
// mDirPathTemp = dirPath;
|
||||
// return (TARGET) this;
|
||||
//}
|
||||
|
||||
//@Override public boolean isRunning() {
|
||||
// DownloadGroupTask task = DownloadGroupTaskQueue.getInstance().getTask(getEntity().getKey());
|
||||
// return task != null && task.isRunning();
|
||||
//}
|
||||
|
||||
///**
|
||||
// * 改变任务组文件夹路径,修改文件夹路径会将子任务所有路径更换
|
||||
// *
|
||||
// * @param newDirPath 新的文件夹路径
|
||||
// */
|
||||
//void reChangeDirPath(String newDirPath) {
|
||||
// List<DTaskWrapper> subTasks = getTaskWrapper().getSubTaskWrapper();
|
||||
// if (subTasks != null && !subTasks.isEmpty()) {
|
||||
// List<DbEntity> des = new ArrayList<>();
|
||||
// for (DTaskWrapper dte : subTasks) {
|
||||
// DownloadEntity de = dte.getEntity();
|
||||
// String oldPath = de.getDownloadPath();
|
||||
// String newPath = newDirPath + "/" + de.getFileName();
|
||||
// File file = new File(oldPath);
|
||||
// if (file.exists()) {
|
||||
// file.renameTo(new File(newPath));
|
||||
// }
|
||||
// de.setDownloadPath(newPath);
|
||||
// des.add(de);
|
||||
// }
|
||||
// AbsEntity.saveAll(des);
|
||||
// }
|
||||
//}
|
||||
|
||||
///**
|
||||
// * 检查并设置文件夹路径
|
||||
// *
|
||||
// * @return {@code true} 合法
|
||||
// */
|
||||
//boolean checkDirPath() {
|
||||
// if (TextUtils.isEmpty(mDirPathTemp)) {
|
||||
// ALog.e(TAG, "文件夹路径不能为null");
|
||||
// return false;
|
||||
// } else if (!mDirPathTemp.startsWith("/")) {
|
||||
// ALog.e(TAG, "文件夹路径【" + mDirPathTemp + "】错误");
|
||||
// return false;
|
||||
// }
|
||||
// File file = new File(mDirPathTemp);
|
||||
// if (file.isFile()) {
|
||||
// ALog.e(TAG, "路径【" + mDirPathTemp + "】是文件,请设置文件夹路径");
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// if (TextUtils.isEmpty(getEntity().getDirPath()) || !getEntity().getDirPath()
|
||||
// .equals(mDirPathTemp)) {
|
||||
// if (!file.exists()) {
|
||||
// file.mkdirs();
|
||||
// }
|
||||
// needModifyPath = true;
|
||||
// getEntity().setDirPath(mDirPathTemp);
|
||||
// ALog.i(TAG, String.format("文件夹路径改变,将更新文件夹路径为:%s", mDirPathTemp));
|
||||
// }
|
||||
//
|
||||
// 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.download; |
||||
|
||||
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; |
||||
import com.arialyy.aria.util.ALog; |
||||
import java.io.File; |
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* Created by lyy on 2017/7/26. |
||||
*/ |
||||
abstract class AbsDGTarget<TARGET extends AbsDGTarget> extends AbsTarget<TARGET> { |
||||
|
||||
private SubTaskManager mSubTaskManager; |
||||
|
||||
/** |
||||
* 获取子任务管理器 |
||||
* |
||||
* @return 子任务管理器 |
||||
*/ |
||||
@CheckResult |
||||
public SubTaskManager getSubTaskManager() { |
||||
if (mSubTaskManager == null) { |
||||
mSubTaskManager = new SubTaskManager(getTargetName(), getTaskWrapper()); |
||||
} |
||||
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; |
||||
getEntity().setAlias(alias); |
||||
return (TARGET) this; |
||||
} |
||||
} |
||||
|
@ -1,147 +1,156 @@ |
||||
/* |
||||
* 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.support.annotation.CheckResult; |
||||
import android.support.annotation.NonNull; |
||||
import com.arialyy.aria.core.common.http.GetDelegate; |
||||
import com.arialyy.aria.core.common.http.HttpHeaderDelegate; |
||||
import com.arialyy.aria.core.common.http.PostDelegate; |
||||
import com.arialyy.aria.core.inf.IHttpHeaderDelegate; |
||||
import java.net.Proxy; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* Created by lyy on 2016/12/5. |
||||
* https://github.com/AriaLyy/Aria
|
||||
*/ |
||||
public class DownloadTarget extends AbsDTarget<DownloadTarget> |
||||
implements IHttpHeaderDelegate<DownloadTarget> { |
||||
private HttpHeaderDelegate<DownloadTarget> mHeaderDelegate; |
||||
private DNormalDelegate<DownloadTarget> mNormalDelegate; |
||||
|
||||
DownloadTarget(DownloadEntity entity, String targetName) { |
||||
this(entity.getUrl(), targetName); |
||||
} |
||||
|
||||
DownloadTarget(String url, String targetName) { |
||||
mNormalDelegate = new DNormalDelegate<>(this, url, targetName); |
||||
mHeaderDelegate = new HttpHeaderDelegate<>(this); |
||||
} |
||||
|
||||
/** |
||||
* Post处理 |
||||
*/ |
||||
@CheckResult |
||||
public PostDelegate asPost() { |
||||
return new PostDelegate<>(this); |
||||
} |
||||
|
||||
/** |
||||
* get参数传递 |
||||
*/ |
||||
@CheckResult |
||||
public GetDelegate asGet() { |
||||
return new GetDelegate<>(this); |
||||
} |
||||
|
||||
/** |
||||
* 是否使用服务器通过content-disposition传递的文件名,内容格式{@code attachment;filename=***} |
||||
* 如果获取不到服务器文件名,则使用用户设置的文件名 |
||||
* |
||||
* @param use {@code true} 使用 |
||||
*/ |
||||
@CheckResult |
||||
public DownloadTarget useServerFileName(boolean use) { |
||||
getTaskWrapper().asHttp().setUseServerFileName(use); |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* 设置文件存储路径,如果需要修改新的文件名,修改路径便可。 |
||||
* 如:原文件路径 /mnt/sdcard/test.zip |
||||
* 如果需要将test.zip改为game.zip,只需要重新设置文件路径为:/mnt/sdcard/game.zip |
||||
* |
||||
* @param filePath 路径必须为文件路径,不能为文件夹路径 |
||||
*/ |
||||
@CheckResult |
||||
public DownloadTarget setFilePath(@NonNull String filePath) { |
||||
mNormalDelegate.setTempFilePath(filePath); |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* 设置文件存储路径,如果需要修改新的文件名,修改路径便可。 |
||||
* 如:原文件路径 /mnt/sdcard/test.zip |
||||
* 如果需要将test.zip改为game.zip,只需要重新设置文件路径为:/mnt/sdcard/game.zip |
||||
* |
||||
* @param filePath 路径必须为文件路径,不能为文件夹路径 |
||||
* @param forceDownload {@code true}强制下载,不考虑文件路径是否被占用 |
||||
*/ |
||||
@CheckResult |
||||
public DownloadTarget setFilePath(@NonNull String filePath, boolean forceDownload) { |
||||
mNormalDelegate.setTempFilePath(filePath); |
||||
mNormalDelegate.setForceDownload(forceDownload); |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* 从header中获取文件描述信息 |
||||
*/ |
||||
public String getContentDisposition() { |
||||
return getEntity().getDisposition(); |
||||
} |
||||
|
||||
@Override public DownloadTarget updateUrl(String newUrl) { |
||||
return mNormalDelegate.updateUrl(newUrl); |
||||
} |
||||
|
||||
@Override public int getTargetType() { |
||||
return HTTP; |
||||
} |
||||
|
||||
/** |
||||
* 设置URL的代理 |
||||
* |
||||
* @param proxy {@link Proxy} |
||||
*/ |
||||
@CheckResult |
||||
@Override public DownloadTarget setUrlProxy(Proxy proxy) { |
||||
return mHeaderDelegate.setUrlProxy(proxy); |
||||
} |
||||
|
||||
@CheckResult |
||||
@Override public DownloadTarget addHeader(@NonNull String key, @NonNull String value) { |
||||
return mHeaderDelegate.addHeader(key, value); |
||||
} |
||||
|
||||
@CheckResult |
||||
@Override public DownloadTarget addHeaders(Map<String, String> headers) { |
||||
return mHeaderDelegate.addHeaders(headers); |
||||
} |
||||
|
||||
@Override protected boolean checkEntity() { |
||||
return mNormalDelegate.checkEntity(); |
||||
} |
||||
|
||||
@Override public boolean isRunning() { |
||||
return mNormalDelegate.isRunning(); |
||||
} |
||||
|
||||
@Override public boolean taskExists() { |
||||
return mNormalDelegate.taskExists(); |
||||
} |
||||
} |
||||
/* |
||||
* 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.support.annotation.CheckResult; |
||||
import android.support.annotation.NonNull; |
||||
import com.arialyy.aria.core.common.http.GetDelegate; |
||||
import com.arialyy.aria.core.common.http.HttpHeaderDelegate; |
||||
import com.arialyy.aria.core.common.http.PostDelegate; |
||||
import com.arialyy.aria.core.inf.IHttpFileLenAdapter; |
||||
import com.arialyy.aria.core.inf.IHttpHeaderDelegate; |
||||
import java.net.Proxy; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* Created by lyy on 2016/12/5. |
||||
* https://github.com/AriaLyy/Aria
|
||||
*/ |
||||
public class DownloadTarget extends AbsDTarget<DownloadTarget> |
||||
implements IHttpHeaderDelegate<DownloadTarget> { |
||||
private HttpHeaderDelegate<DownloadTarget> mHeaderDelegate; |
||||
private DNormalDelegate<DownloadTarget> mNormalDelegate; |
||||
|
||||
DownloadTarget(DownloadEntity entity, String targetName) { |
||||
this(entity.getUrl(), targetName); |
||||
} |
||||
|
||||
DownloadTarget(String url, String targetName) { |
||||
mNormalDelegate = new DNormalDelegate<>(this, url, targetName); |
||||
mHeaderDelegate = new HttpHeaderDelegate<>(this); |
||||
} |
||||
|
||||
/** |
||||
* Post处理 |
||||
*/ |
||||
@CheckResult |
||||
public PostDelegate asPost() { |
||||
return new PostDelegate<>(this); |
||||
} |
||||
|
||||
/** |
||||
* get参数传递 |
||||
*/ |
||||
@CheckResult |
||||
public GetDelegate asGet() { |
||||
return new GetDelegate<>(this); |
||||
} |
||||
|
||||
/** |
||||
* 是否使用服务器通过content-disposition传递的文件名,内容格式{@code attachment;filename=***} |
||||
* 如果获取不到服务器文件名,则使用用户设置的文件名 |
||||
* |
||||
* @param use {@code true} 使用 |
||||
*/ |
||||
@CheckResult |
||||
public DownloadTarget useServerFileName(boolean use) { |
||||
getTaskWrapper().asHttp().setUseServerFileName(use); |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* 设置文件存储路径,如果需要修改新的文件名,修改路径便可。 |
||||
* 如:原文件路径 /mnt/sdcard/test.zip |
||||
* 如果需要将test.zip改为game.zip,只需要重新设置文件路径为:/mnt/sdcard/game.zip |
||||
* |
||||
* @param filePath 路径必须为文件路径,不能为文件夹路径 |
||||
*/ |
||||
@CheckResult |
||||
public DownloadTarget setFilePath(@NonNull String filePath) { |
||||
mNormalDelegate.setTempFilePath(filePath); |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* 设置文件存储路径,如果需要修改新的文件名,修改路径便可。 |
||||
* 如:原文件路径 /mnt/sdcard/test.zip |
||||
* 如果需要将test.zip改为game.zip,只需要重新设置文件路径为:/mnt/sdcard/game.zip |
||||
* |
||||
* @param filePath 路径必须为文件路径,不能为文件夹路径 |
||||
* @param forceDownload {@code true}强制下载,不考虑文件路径是否被占用 |
||||
*/ |
||||
@CheckResult |
||||
public DownloadTarget setFilePath(@NonNull String filePath, boolean forceDownload) { |
||||
mNormalDelegate.setTempFilePath(filePath); |
||||
mNormalDelegate.setForceDownload(forceDownload); |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* 如果你需要使用header中特定的key来设置文件长度,或有定制文件长度的需要,那么你可以通过该方法自行处理文件长度 |
||||
*/ |
||||
public DownloadTarget setFileLenAdapter(IHttpFileLenAdapter adapter) { |
||||
//return mHeaderDelegate.setFileLenAdapter(adapter);
|
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* 从header中获取文件描述信息 |
||||
*/ |
||||
public String getContentDisposition() { |
||||
return getEntity().getDisposition(); |
||||
} |
||||
|
||||
@Override public DownloadTarget updateUrl(String newUrl) { |
||||
return mNormalDelegate.updateUrl(newUrl); |
||||
} |
||||
|
||||
@Override public int getTargetType() { |
||||
return HTTP; |
||||
} |
||||
|
||||
/** |
||||
* 设置URL的代理 |
||||
* |
||||
* @param proxy {@link Proxy} |
||||
*/ |
||||
@CheckResult |
||||
@Override public DownloadTarget setUrlProxy(Proxy proxy) { |
||||
return mHeaderDelegate.setUrlProxy(proxy); |
||||
} |
||||
|
||||
@CheckResult |
||||
@Override public DownloadTarget addHeader(@NonNull String key, @NonNull String value) { |
||||
return mHeaderDelegate.addHeader(key, value); |
||||
} |
||||
|
||||
@CheckResult |
||||
@Override public DownloadTarget addHeaders(Map<String, String> headers) { |
||||
return mHeaderDelegate.addHeaders(headers); |
||||
} |
||||
|
||||
@Override protected boolean checkEntity() { |
||||
return mNormalDelegate.checkEntity(); |
||||
} |
||||
|
||||
@Override public boolean isRunning() { |
||||
return mNormalDelegate.isRunning(); |
||||
} |
||||
|
||||
@Override public boolean taskExists() { |
||||
return mNormalDelegate.taskExists(); |
||||
} |
||||
} |
||||
|
@ -0,0 +1,10 @@ |
||||
package com.arialyy.aria.core.inf; |
||||
|
||||
public abstract class AbsHttpFileLenAdapter implements IHttpFileLenAdapter { |
||||
|
||||
@Override public Object clone() throws CloneNotSupportedException { |
||||
//AbsHttpFileLenAdapter newAdapter = super.clone();
|
||||
|
||||
return super.clone(); |
||||
} |
||||
} |
@ -1,348 +1,340 @@ |
||||
/* |
||||
* 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.inf; |
||||
|
||||
import android.support.annotation.CheckResult; |
||||
import android.text.TextUtils; |
||||
import com.arialyy.aria.core.AriaManager; |
||||
import com.arialyy.aria.core.command.ICmd; |
||||
import com.arialyy.aria.core.command.normal.CancelCmd; |
||||
import com.arialyy.aria.core.command.normal.NormalCmdFactory; |
||||
import com.arialyy.aria.core.common.TaskRecord; |
||||
import com.arialyy.aria.core.download.DGTaskWrapper; |
||||
import com.arialyy.aria.core.download.DownloadGroupEntity; |
||||
import com.arialyy.aria.core.download.DTaskWrapper; |
||||
import com.arialyy.aria.core.manager.TaskWrapperManager; |
||||
import com.arialyy.aria.core.upload.UTaskWrapper; |
||||
import com.arialyy.aria.orm.DbEntity; |
||||
import com.arialyy.aria.util.ALog; |
||||
import com.arialyy.aria.util.CommonUtil; |
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* Created by AriaL on 2017/7/3. |
||||
*/ |
||||
public abstract class AbsTarget<TARGET extends AbsTarget> implements ITargetHandler { |
||||
|
||||
protected String TAG; |
||||
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()} |
||||
* 等操作任务的方法,那么你需要调用{@link #save()}才能将修改保存到数据库 |
||||
*/ |
||||
@CheckResult(suggest = "after use #start()、#stop()、#cancel()、#resume()、#save()?") |
||||
public TARGET resetState() { |
||||
mTaskWrapper.getEntity().setState(IEntity.STATE_WAIT); |
||||
mTaskWrapper.setRefreshInfo(true); |
||||
return (TARGET) this; |
||||
} |
||||
|
||||
/** |
||||
* 删除记录,如果任务正在执行,则会删除正在下载的任务 |
||||
*/ |
||||
public void removeRecord() { |
||||
if (isRunning()) { |
||||
ALog.d("AbsTarget", "任务正在下载,即将删除任务"); |
||||
cancel(); |
||||
} else { |
||||
if (mEntity instanceof AbsNormalEntity) { |
||||
TaskRecord record = |
||||
DbEntity.findFirst(TaskRecord.class, "TaskRecord.filePath=?", mTaskWrapper.getKey()); |
||||
if (record != null) { |
||||
CommonUtil.delTaskRecord(record, mTaskWrapper.isRemoveFile(), (AbsNormalEntity) mEntity); |
||||
} else { |
||||
mEntity.deleteData(); |
||||
} |
||||
} else if (mEntity instanceof DownloadGroupEntity) { |
||||
CommonUtil.delGroupTaskRecord(mTaskWrapper.isRemoveFile(), ((DownloadGroupEntity) mEntity)); |
||||
} |
||||
TaskWrapperManager.getInstance().removeTaskWrapper(mEntity.getKey()); |
||||
} |
||||
} |
||||
|
||||
public AbsEntity getEntity() { |
||||
return mEntity; |
||||
} |
||||
|
||||
public String getTargetName() { |
||||
return mTargetName; |
||||
} |
||||
|
||||
public void setTargetName(String mTargetName) { |
||||
this.mTargetName = mTargetName; |
||||
} |
||||
|
||||
/** |
||||
* 获取任务实体 |
||||
*/ |
||||
public AbsTaskWrapper getTaskWrapper() { |
||||
return mTaskWrapper; |
||||
} |
||||
|
||||
/** |
||||
* 获取任务进度,如果任务存在,则返回当前进度 |
||||
* |
||||
* @return 该任务进度 |
||||
*/ |
||||
public long getCurrentProgress() { |
||||
return mEntity == null ? -1 : mEntity.getCurrentProgress(); |
||||
} |
||||
|
||||
/** |
||||
* 获取任务文件大小 |
||||
* |
||||
* @return 文件大小 |
||||
*/ |
||||
public long getFileSize() { |
||||
return mEntity == null ? 0 : mEntity.getFileSize(); |
||||
} |
||||
|
||||
/** |
||||
* 获取单位转换后的文件大小 |
||||
* |
||||
* @return 文件大小{@code xxx mb} |
||||
*/ |
||||
public String getConvertFileSize() { |
||||
return mEntity == null ? "0b" : CommonUtil.formatFileSize(mEntity.getFileSize()); |
||||
} |
||||
|
||||
/** |
||||
* 设置扩展字段,用来保存你的其它数据,如果你的数据比较多,你可以把你的数据转换为JSON字符串,然后再存到Aria中 |
||||
* 注意:如果在后续方法调用链中没有调用 {@link #start()}、{@link #stop()}、{@link #cancel()}、{@link #resume()} |
||||
* 等操作任务的方法,那么你需要调用{@link #save()}才能将修改保存到数据库 |
||||
* |
||||
* @param str 扩展数据 |
||||
*/ |
||||
@CheckResult(suggest = "after use #start()、#stop()、#cancel()、#resume()、#save()?") |
||||
public TARGET setExtendField(String str) { |
||||
if (TextUtils.isEmpty(str)) return (TARGET) this; |
||||
if (TextUtils.isEmpty(mEntity.getStr()) || !mEntity.getStr().equals(str)) { |
||||
mEntity.setStr(str); |
||||
} else { |
||||
ALog.e(TAG, "设置扩展字段失败,扩展字段为一致"); |
||||
} |
||||
|
||||
return (TARGET) this; |
||||
} |
||||
|
||||
/** |
||||
* 获取存放的扩展字段 |
||||
* 设置扩展字段{@link #setExtendField(String)} |
||||
*/ |
||||
public String getExtendField() { |
||||
return mEntity.getStr(); |
||||
} |
||||
|
||||
/** |
||||
* 获取任务状态 |
||||
* |
||||
* @return {@link IEntity} |
||||
*/ |
||||
public int getTaskState() { |
||||
return mEntity.getState(); |
||||
} |
||||
|
||||
/** |
||||
* 获取任务进度百分比 |
||||
* |
||||
* @return 返回任务进度 |
||||
*/ |
||||
public int getPercent() { |
||||
if (mEntity == null) { |
||||
ALog.e("AbsTarget", "下载管理器中没有该任务"); |
||||
return 0; |
||||
} |
||||
if (mEntity.getFileSize() != 0) { |
||||
return (int) (mEntity.getCurrentProgress() * 100 / mEntity.getFileSize()); |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
/** |
||||
* 检查实体是否合法,如果实体合法,将保存实体到数据库,或更新数据库中的实体对象 |
||||
* |
||||
* @return {@code true} 合法 |
||||
*/ |
||||
protected abstract boolean checkEntity(); |
||||
|
||||
protected int checkTaskType() { |
||||
int taskType = 0; |
||||
if (mTaskWrapper instanceof DTaskWrapper) { |
||||
taskType = ICmd.TASK_TYPE_DOWNLOAD; |
||||
} else if (mTaskWrapper instanceof DGTaskWrapper) { |
||||
taskType = ICmd.TASK_TYPE_DOWNLOAD_GROUP; |
||||
} else if (mTaskWrapper instanceof UTaskWrapper) { |
||||
taskType = ICmd.TASK_TYPE_UPLOAD; |
||||
} |
||||
return taskType; |
||||
} |
||||
|
||||
/** |
||||
* 保存修改 |
||||
*/ |
||||
@Override public void save() { |
||||
if (!checkEntity()) { |
||||
ALog.e(TAG, "保存修改失败"); |
||||
} else { |
||||
ALog.i(TAG, "保存成功"); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 任务是否在执行 |
||||
* |
||||
* @return {@code true} 任务正在执行 |
||||
*/ |
||||
public abstract boolean isRunning(); |
||||
|
||||
/** |
||||
* 任务是否存在 |
||||
* |
||||
* @return {@code true} 任务存在 |
||||
*/ |
||||
public abstract boolean taskExists(); |
||||
|
||||
/** |
||||
* 设置target类型 |
||||
* |
||||
* @return {@link #HTTP}、{@link #FTP}、{@link #GROUP_HTTP}、{@link #GROUP_FTP_DIR} |
||||
*/ |
||||
public abstract int getTargetType(); |
||||
|
||||
/** |
||||
* 添加任务 |
||||
*/ |
||||
@Override public void add() { |
||||
if (checkEntity()) { |
||||
AriaManager.getInstance(AriaManager.APP) |
||||
.setCmd(CommonUtil.createNormalCmd(getTaskWrapper(), NormalCmdFactory.TASK_CREATE, |
||||
checkTaskType())) |
||||
.exe(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 开始任务 |
||||
*/ |
||||
@Override public void start() { |
||||
if (checkEntity()) { |
||||
AriaManager.getInstance(AriaManager.APP) |
||||
.setCmd( |
||||
CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_START, |
||||
checkTaskType())) |
||||
.exe(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 停止任务 |
||||
* |
||||
* @see #stop() |
||||
*/ |
||||
@Deprecated public void pause() { |
||||
if (checkEntity()) { |
||||
stop(); |
||||
} |
||||
} |
||||
|
||||
@Override public void stop() { |
||||
if (checkEntity()) { |
||||
AriaManager.getInstance(AriaManager.APP) |
||||
.setCmd( |
||||
CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_STOP, checkTaskType())) |
||||
.exe(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 恢复任务 |
||||
*/ |
||||
@Override public void resume() { |
||||
if (checkEntity()) { |
||||
AriaManager.getInstance(AriaManager.APP) |
||||
.setCmd( |
||||
CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_START, |
||||
checkTaskType())) |
||||
.exe(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 删除任务 |
||||
*/ |
||||
@Override public void cancel() { |
||||
if (checkEntity()) { |
||||
AriaManager.getInstance(AriaManager.APP) |
||||
.setCmd(CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_CANCEL, |
||||
checkTaskType())) |
||||
.exe(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 任务重试 |
||||
*/ |
||||
@Override public void reTry() { |
||||
if (checkEntity()) { |
||||
List<ICmd> cmds = new ArrayList<>(); |
||||
int taskType = checkTaskType(); |
||||
cmds.add( |
||||
CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_STOP, taskType)); |
||||
cmds.add(CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_START, taskType)); |
||||
AriaManager.getInstance(AriaManager.APP).setCmds(cmds).exe(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 删除任务 |
||||
* |
||||
* @param removeFile {@code true} 不仅删除任务数据库记录,还会删除已经删除完成的文件 |
||||
* {@code false}如果任务已经完成,只删除任务数据库记录, |
||||
*/ |
||||
@Override public void cancel(boolean removeFile) { |
||||
if (checkEntity()) { |
||||
CancelCmd cancelCmd = |
||||
(CancelCmd) CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_CANCEL, |
||||
checkTaskType()); |
||||
cancelCmd.removeFile = removeFile; |
||||
AriaManager.getInstance(AriaManager.APP).setCmd(cancelCmd).exe(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 重新下载 |
||||
*/ |
||||
@Override public void reStart() { |
||||
if (checkEntity()) { |
||||
cancel(); |
||||
start(); |
||||
} |
||||
} |
||||
} |
||||
/* |
||||
* 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.inf; |
||||
|
||||
import android.support.annotation.CheckResult; |
||||
import android.text.TextUtils; |
||||
import com.arialyy.aria.core.AriaManager; |
||||
import com.arialyy.aria.core.command.ICmd; |
||||
import com.arialyy.aria.core.command.normal.CancelCmd; |
||||
import com.arialyy.aria.core.command.normal.NormalCmdFactory; |
||||
import com.arialyy.aria.core.download.DGTaskWrapper; |
||||
import com.arialyy.aria.core.download.DownloadGroupEntity; |
||||
import com.arialyy.aria.core.download.DTaskWrapper; |
||||
import com.arialyy.aria.core.manager.TaskWrapperManager; |
||||
import com.arialyy.aria.core.upload.UTaskWrapper; |
||||
import com.arialyy.aria.util.ALog; |
||||
import com.arialyy.aria.util.CommonUtil; |
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* Created by AriaL on 2017/7/3. |
||||
*/ |
||||
public abstract class AbsTarget<TARGET extends AbsTarget> implements ITargetHandler { |
||||
|
||||
protected String TAG; |
||||
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()} |
||||
* 等操作任务的方法,那么你需要调用{@link #save()}才能将修改保存到数据库 |
||||
*/ |
||||
@CheckResult(suggest = "after use #start()、#stop()、#cancel()、#resume()、#save()?") |
||||
public TARGET resetState() { |
||||
mTaskWrapper.getEntity().setState(IEntity.STATE_WAIT); |
||||
mTaskWrapper.setRefreshInfo(true); |
||||
return (TARGET) this; |
||||
} |
||||
|
||||
/** |
||||
* 删除记录,如果任务正在执行,则会删除正在下载的任务 |
||||
*/ |
||||
public void removeRecord() { |
||||
if (isRunning()) { |
||||
ALog.d("AbsTarget", "任务正在下载,即将删除任务"); |
||||
cancel(); |
||||
} else { |
||||
if (mEntity instanceof AbsNormalEntity) { |
||||
CommonUtil.delTaskRecord((AbsNormalEntity) mEntity, mTaskWrapper.isRemoveFile()); |
||||
} else if (mEntity instanceof DownloadGroupEntity) { |
||||
CommonUtil.delGroupTaskRecord(((DownloadGroupEntity) mEntity), mTaskWrapper.isRemoveFile()); |
||||
} |
||||
TaskWrapperManager.getInstance().removeTaskWrapper(mEntity.getKey()); |
||||
} |
||||
} |
||||
|
||||
public AbsEntity getEntity() { |
||||
return mEntity; |
||||
} |
||||
|
||||
public String getTargetName() { |
||||
return mTargetName; |
||||
} |
||||
|
||||
public void setTargetName(String mTargetName) { |
||||
this.mTargetName = mTargetName; |
||||
} |
||||
|
||||
/** |
||||
* 获取任务实体 |
||||
*/ |
||||
public AbsTaskWrapper getTaskWrapper() { |
||||
return mTaskWrapper; |
||||
} |
||||
|
||||
/** |
||||
* 获取任务进度,如果任务存在,则返回当前进度 |
||||
* |
||||
* @return 该任务进度 |
||||
*/ |
||||
public long getCurrentProgress() { |
||||
return mEntity == null ? -1 : mEntity.getCurrentProgress(); |
||||
} |
||||
|
||||
/** |
||||
* 获取任务文件大小 |
||||
* |
||||
* @return 文件大小 |
||||
*/ |
||||
public long getFileSize() { |
||||
return mEntity == null ? 0 : mEntity.getFileSize(); |
||||
} |
||||
|
||||
/** |
||||
* 获取单位转换后的文件大小 |
||||
* |
||||
* @return 文件大小{@code xxx mb} |
||||
*/ |
||||
public String getConvertFileSize() { |
||||
return mEntity == null ? "0b" : CommonUtil.formatFileSize(mEntity.getFileSize()); |
||||
} |
||||
|
||||
/** |
||||
* 设置扩展字段,用来保存你的其它数据,如果你的数据比较多,你可以把你的数据转换为JSON字符串,然后再存到Aria中 |
||||
* 注意:如果在后续方法调用链中没有调用 {@link #start()}、{@link #stop()}、{@link #cancel()}、{@link #resume()} |
||||
* 等操作任务的方法,那么你需要调用{@link #save()}才能将修改保存到数据库 |
||||
* |
||||
* @param str 扩展数据 |
||||
*/ |
||||
@CheckResult(suggest = "after use #start()、#stop()、#cancel()、#resume()、#save()?") |
||||
public TARGET setExtendField(String str) { |
||||
if (TextUtils.isEmpty(str)) return (TARGET) this; |
||||
if (TextUtils.isEmpty(mEntity.getStr()) || !mEntity.getStr().equals(str)) { |
||||
mEntity.setStr(str); |
||||
} else { |
||||
ALog.e(TAG, "设置扩展字段失败,扩展字段为一致"); |
||||
} |
||||
|
||||
return (TARGET) this; |
||||
} |
||||
|
||||
/** |
||||
* 获取存放的扩展字段 |
||||
* 设置扩展字段{@link #setExtendField(String)} |
||||
*/ |
||||
public String getExtendField() { |
||||
return mEntity.getStr(); |
||||
} |
||||
|
||||
/** |
||||
* 获取任务状态 |
||||
* |
||||
* @return {@link IEntity} |
||||
*/ |
||||
public int getTaskState() { |
||||
return mEntity.getState(); |
||||
} |
||||
|
||||
/** |
||||
* 获取任务进度百分比 |
||||
* |
||||
* @return 返回任务进度 |
||||
*/ |
||||
public int getPercent() { |
||||
if (mEntity == null) { |
||||
ALog.e("AbsTarget", "下载管理器中没有该任务"); |
||||
return 0; |
||||
} |
||||
if (mEntity.getFileSize() != 0) { |
||||
return (int) (mEntity.getCurrentProgress() * 100 / mEntity.getFileSize()); |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
/** |
||||
* 检查实体是否合法,如果实体合法,将保存实体到数据库,或更新数据库中的实体对象 |
||||
* |
||||
* @return {@code true} 合法 |
||||
*/ |
||||
protected abstract boolean checkEntity(); |
||||
|
||||
protected int checkTaskType() { |
||||
int taskType = 0; |
||||
if (mTaskWrapper instanceof DTaskWrapper) { |
||||
taskType = ICmd.TASK_TYPE_DOWNLOAD; |
||||
} else if (mTaskWrapper instanceof DGTaskWrapper) { |
||||
taskType = ICmd.TASK_TYPE_DOWNLOAD_GROUP; |
||||
} else if (mTaskWrapper instanceof UTaskWrapper) { |
||||
taskType = ICmd.TASK_TYPE_UPLOAD; |
||||
} |
||||
return taskType; |
||||
} |
||||
|
||||
/** |
||||
* 保存修改 |
||||
*/ |
||||
@Override public void save() { |
||||
if (!checkEntity()) { |
||||
ALog.e(TAG, "保存修改失败"); |
||||
} else { |
||||
ALog.i(TAG, "保存成功"); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 任务是否在执行 |
||||
* |
||||
* @return {@code true} 任务正在执行 |
||||
*/ |
||||
public abstract boolean isRunning(); |
||||
|
||||
/** |
||||
* 任务是否存在 |
||||
* |
||||
* @return {@code true} 任务存在 |
||||
*/ |
||||
public abstract boolean taskExists(); |
||||
|
||||
/** |
||||
* 设置target类型 |
||||
* |
||||
* @return {@link #HTTP}、{@link #FTP}、{@link #GROUP_HTTP}、{@link #GROUP_FTP_DIR} |
||||
*/ |
||||
public abstract int getTargetType(); |
||||
|
||||
/** |
||||
* 添加任务 |
||||
*/ |
||||
@Override public void add() { |
||||
if (checkEntity()) { |
||||
AriaManager.getInstance(AriaManager.APP) |
||||
.setCmd(CommonUtil.createNormalCmd(getTaskWrapper(), NormalCmdFactory.TASK_CREATE, |
||||
checkTaskType())) |
||||
.exe(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 开始任务 |
||||
*/ |
||||
@Override public void start() { |
||||
if (checkEntity()) { |
||||
AriaManager.getInstance(AriaManager.APP) |
||||
.setCmd( |
||||
CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_START, |
||||
checkTaskType())) |
||||
.exe(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 停止任务 |
||||
* |
||||
* @see #stop() |
||||
*/ |
||||
@Deprecated public void pause() { |
||||
if (checkEntity()) { |
||||
stop(); |
||||
} |
||||
} |
||||
|
||||
@Override public void stop() { |
||||
if (checkEntity()) { |
||||
AriaManager.getInstance(AriaManager.APP) |
||||
.setCmd( |
||||
CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_STOP, checkTaskType())) |
||||
.exe(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 恢复任务 |
||||
*/ |
||||
@Override public void resume() { |
||||
if (checkEntity()) { |
||||
AriaManager.getInstance(AriaManager.APP) |
||||
.setCmd( |
||||
CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_START, |
||||
checkTaskType())) |
||||
.exe(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 删除任务 |
||||
*/ |
||||
@Override public void cancel() { |
||||
if (checkEntity()) { |
||||
AriaManager.getInstance(AriaManager.APP) |
||||
.setCmd(CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_CANCEL, |
||||
checkTaskType())) |
||||
.exe(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 任务重试 |
||||
*/ |
||||
@Override public void reTry() { |
||||
if (checkEntity()) { |
||||
List<ICmd> cmds = new ArrayList<>(); |
||||
int taskType = checkTaskType(); |
||||
cmds.add( |
||||
CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_STOP, taskType)); |
||||
cmds.add(CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_START, taskType)); |
||||
AriaManager.getInstance(AriaManager.APP).setCmds(cmds).exe(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 删除任务 |
||||
* |
||||
* @param removeFile {@code true} 不仅删除任务数据库记录,还会删除已经删除完成的文件 |
||||
* {@code false}如果任务已经完成,只删除任务数据库记录, |
||||
*/ |
||||
@Override public void cancel(boolean removeFile) { |
||||
if (checkEntity()) { |
||||
CancelCmd cancelCmd = |
||||
(CancelCmd) CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_CANCEL, |
||||
checkTaskType()); |
||||
cancelCmd.removeFile = removeFile; |
||||
AriaManager.getInstance(AriaManager.APP).setCmd(cancelCmd).exe(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 重新下载 |
||||
*/ |
||||
@Override public void reStart() { |
||||
if (checkEntity()) { |
||||
cancel(); |
||||
start(); |
||||
} |
||||
} |
||||
} |
||||
|
@ -0,0 +1,36 @@ |
||||
/* |
||||
* 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.inf; |
||||
|
||||
import java.io.Serializable; |
||||
import java.net.URLConnection; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* Http文件长度适配器 |
||||
*/ |
||||
public interface IHttpFileLenAdapter extends Serializable { |
||||
long serialVersionUID = 1L; |
||||
|
||||
/** |
||||
* 同伙header中的数据获取文件长度 |
||||
* |
||||
* @param headers header参数{@link URLConnection#getHeaderFields()} |
||||
* @return 文件长度 |
||||
*/ |
||||
long handleFileLen(Map<String, List<String>> headers); |
||||
} |
@ -1,194 +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(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; |
||||
} |
||||
} |
||||
/* |
||||
* 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 getTaskWrapper().getConfig(); |
||||
} |
||||
|
||||
@Override public FtpThreadTask call() throws Exception { |
||||
super.call(); |
||||
//当前子线程的下载位置
|
||||
mChildCurrentLocation = getConfig().START_LOCATION; |
||||
FTPClient client = null; |
||||
BufferedRandomAccessFile file = null; |
||||
try { |
||||
ALog.d(TAG, |
||||
String.format("任务【%s】线程__%s__开始上传【开始位置 : %s,结束位置:%s】", getConfig().TEMP_FILE.getName(), |
||||
getConfig().THREAD_ID, getConfig().START_LOCATION, getConfig().END_LOCATION)); |
||||
client = createClient(); |
||||
if (client == null) { |
||||
return this; |
||||
} |
||||
initPath(); |
||||
client.makeDirectory(dir); |
||||
client.changeWorkingDirectory(dir); |
||||
client.setRestartOffset(getConfig().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(), getEntity().getFilePath()))); |
||||
client.disconnect(); |
||||
return this; |
||||
} |
||||
|
||||
file = new BufferedRandomAccessFile(getConfig().TEMP_FILE, "rwd", getTaskConfig().getBuffSize()); |
||||
if (getConfig().START_LOCATION != 0) { |
||||
//file.skipBytes((int) getConfig().START_LOCATION);
|
||||
file.seek(getConfig().START_LOCATION); |
||||
} |
||||
boolean complete = upload(client, file); |
||||
if (!complete || isBreak()) { |
||||
return this; |
||||
} |
||||
ALog.i(TAG, |
||||
String.format("任务【%s】线程__%s__上传完毕", getConfig().TEMP_FILE.getName(), getConfig().THREAD_ID)); |
||||
writeConfig(true, getConfig().END_LOCATION); |
||||
getState().COMPLETE_THREAD_NUM++; |
||||
if (getState().isComplete()) { |
||||
getState().TASK_RECORD.deleteData(); |
||||
getState().isRunning = false; |
||||
mListener.onComplete(); |
||||
} |
||||
if (getState().isFail()) { |
||||
getState().isRunning = false; |
||||
mListener.onFail(false, new TaskException(TAG, |
||||
String.format("上传失败,filePath: %s, uploadUrl: %s", getEntity().getFilePath(), getConfig().URL))); |
||||
} |
||||
} catch (IOException e) { |
||||
fail(mChildCurrentLocation, new AriaIOException(TAG, |
||||
String.format("上传失败,filePath: %s, uploadUrl: %s", getEntity().getFilePath(), getConfig().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(getTaskWrapper().asFtp().getUrlEntity().remotePath.getBytes(charSet), |
||||
SERVER_CHARSET); |
||||
remotePath = new String(String.format("%s/%s", getTaskWrapper().asFtp().getUrlEntity().remotePath, |
||||
getEntity().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(), getEntity().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(), getEntity().getFilePath()))); |
||||
} |
||||
if (client.isConnected()) { |
||||
client.disconnect(); |
||||
} |
||||
return false; |
||||
} |
||||
return true; |
||||
} |
||||
} |
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue