ftp 断点上传

pull/330/head
AriaLyy 7 years ago
parent 4f40341ee9
commit 867289bc86
  1. 3
      .gitignore
  2. 49
      Aria/src/main/java/com/arialyy/aria/core/common/AbsFileer.java
  3. 3
      Aria/src/main/java/com/arialyy/aria/core/common/AbsThreadTask.java
  4. 4
      Aria/src/main/java/com/arialyy/aria/core/download/BaseDListener.java
  5. 3
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupListener.java
  6. 2
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadListener.java
  7. 10
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadTask.java
  8. 4
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpFileInfoThread.java
  9. 4
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/SimpleDownloadUtil.java
  10. 21
      Aria/src/main/java/com/arialyy/aria/core/inf/AbsTarget.java
  11. 14
      Aria/src/main/java/com/arialyy/aria/core/inf/IReceiver.java
  12. 4
      Aria/src/main/java/com/arialyy/aria/core/inf/IUploadListener.java
  13. 18
      Aria/src/main/java/com/arialyy/aria/core/scheduler/ISchedulerListener.java
  14. 138
      Aria/src/main/java/com/arialyy/aria/core/upload/BaseUListener.java
  15. 4
      Aria/src/main/java/com/arialyy/aria/core/upload/UploadListener.java
  16. 3
      Aria/src/main/java/com/arialyy/aria/core/upload/UploadReceiver.java
  17. 1
      Aria/src/main/java/com/arialyy/aria/core/upload/UploadTarget.java
  18. 13
      Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpThreadTask.java
  19. 8
      Aria/src/main/java/com/arialyy/aria/core/upload/uploader/HttpThreadTask.java
  20. 11
      Aria/src/main/java/com/arialyy/aria/core/upload/uploader/SimpleUploadUtil.java
  21. 10
      Aria/src/main/java/com/arialyy/aria/core/upload/uploader/Uploader.java
  22. 14
      Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java
  23. 13
      AriaAnnotations/src/main/java/com/arialyy/annotations/Upload.java
  24. 3
      AriaCompiler/src/main/java/com/arialyy/compiler/AriaProcessor.java
  25. 7
      AriaCompiler/src/main/java/com/arialyy/compiler/ElementHandler.java
  26. 24
      AriaFtpPlug/src/androidTest/java/com/arialyy/ftpplug/ExampleInstrumentedTest.java
  27. 8
      AriaFtpPlug/src/main/java/com/arialyy/ftpplug/Test.java
  28. 16
      AriaFtpPlug/src/test/java/com/arialyy/ftpplug/ExampleUnitTest.java
  29. 1
      app/.gitignore
  30. 2
      app/src/main/AndroidManifest.xml
  31. 2
      app/src/main/assets/aria_config.xml
  32. 4
      app/src/main/java/com/arialyy/simple/MainActivity.java
  33. 11
      app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java
  34. 25
      app/src/main/java/com/arialyy/simple/upload/FtpUploadActivity.java
  35. 65
      app/src/main/java/com/arialyy/simple/upload/HttpUploadActivity.java
  36. 6
      app/src/main/res/layout/activity_main.xml
  37. 6
      app/src/main/res/layout/activity_upload.xml
  38. 128
      aria/src/main/java/com/arialyy/aria/core/upload/UploadTask.java

3
.gitignore vendored

@ -12,4 +12,5 @@
.gradle
/.idea
.idea
/cache
/cache
*.log

@ -99,18 +99,17 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
mConstance.THREAD_NUM = mThreadNum;
handleNoSupportBP();
} else {
mThreadNum = isNewTask ? (getThreadNum()) : mRealThreadNum;
mThreadNum = isNewTask ? (getNewTaskThreadNum()) : mRealThreadNum;
mConstance.THREAD_NUM = mThreadNum;
mFixedThreadPool = Executors.newFixedThreadPool(mThreadNum);
handleBreakpoint();
}
startTimer();
}
/**
* 获取线程数
* 设置新任务的最大线程数
*/
protected int getThreadNum() {
protected int getNewTaskThreadNum() {
return mEntity.getFileSize() <= SUB_LEN || mTaskEntity.requestType == AbsTaskEntity.FTP_DIR ? 1
: AriaManager.getInstance(mContext).getDownloadConfig().getThreadNum();
}
@ -292,25 +291,6 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
return selectThreadTask(config);
}
/**
* 启动单线程下载任务
*/
private void startSingleTask(int[] recordL) {
if (mConstance.CURRENT_LOCATION > 0) {
mListener.onResume(mConstance.CURRENT_LOCATION);
} else {
mListener.onStart(mConstance.CURRENT_LOCATION);
}
mFixedThreadPool = Executors.newFixedThreadPool(recordL.length);
for (int l : recordL) {
if (l == -1) continue;
Runnable task = mTask.get(l);
if (task != null) {
mFixedThreadPool.execute(task);
}
}
}
/**
* 处理断点
*/
@ -358,6 +338,28 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
startSingleTask(recordL);
}
/**
* 启动单线程下载任务
*/
private void startSingleTask(int[] recordL) {
if (mConstance.CURRENT_LOCATION > 0) {
mListener.onResume(mConstance.CURRENT_LOCATION);
} else {
mListener.onStart(mConstance.CURRENT_LOCATION);
}
mFixedThreadPool = Executors.newFixedThreadPool(recordL.length);
for (int l : recordL) {
if (l == -1) continue;
Runnable task = mTask.get(l);
if (task != null) {
mFixedThreadPool.execute(task);
}
}
}
/**
* 处理新任务
*/
protected abstract void handleNewTask();
/**
@ -377,6 +379,7 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
AbsThreadTask task = selectThreadTask(config);
if (task == null) return;
mTask.put(0, task);
mFixedThreadPool = Executors.newFixedThreadPool(1);
mFixedThreadPool.execute(task);
mListener.onStart(0);
}

@ -22,6 +22,7 @@ import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.inf.AbsEntity;
import com.arialyy.aria.core.inf.AbsTaskEntity;
import com.arialyy.aria.core.inf.IEventListener;
import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.util.CommonUtil;
import java.io.File;
import java.io.IOException;
@ -134,7 +135,7 @@ public abstract class AbsThreadTask<ENTITY extends AbsEntity, TASK_ENTITY extend
if (configFile.exists()) {
configFile.delete();
}
if (mConfig.TEMP_FILE.exists()) {
if (mConfig.TEMP_FILE.exists() && !(mEntity instanceof UploadEntity)) {
mConfig.TEMP_FILE.delete();
}
Log.d(TAG, "任务【" + mConfig.TEMP_FILE.getName() + "】已取消");

@ -30,7 +30,7 @@ import java.lang.ref.WeakReference;
/**
* 下载监听类
*/
class BaseListener<ENTITY extends AbsEntity, TASK extends AbsTask<ENTITY>>
class BaseDListener<ENTITY extends AbsEntity, TASK extends AbsTask<ENTITY>>
implements IDownloadListener {
private WeakReference<Handler> outHandler;
private long mLastLen = 0; //上一次发送长度
@ -40,7 +40,7 @@ class BaseListener<ENTITY extends AbsEntity, TASK extends AbsTask<ENTITY>>
private boolean isConvertSpeed = false;
boolean isWait = false;
BaseListener(TASK task, Handler outHandler) {
BaseDListener(TASK task, Handler outHandler) {
this.outHandler = new WeakReference<>(outHandler);
this.mTask = new WeakReference<>(task).get();
this.mEntity = this.mTask.getEntity();

@ -16,14 +16,13 @@
package com.arialyy.aria.core.download;
import android.os.Handler;
import android.util.Log;
import com.arialyy.aria.core.download.downloader.IDownloadGroupListener;
/**
* Created by Aria.Lao on 2017/7/20.
* 任务组下载事件
*/
class DownloadGroupListener extends BaseListener<DownloadGroupEntity, DownloadGroupTask>
class DownloadGroupListener extends BaseDListener<DownloadGroupEntity, DownloadGroupTask>
implements IDownloadGroupListener {
private final String TAG = "DownloadGroupListener";

@ -22,7 +22,7 @@ import com.arialyy.aria.core.inf.IDownloadListener;
* Created by Aria.Lao on 2017/7/20.
* 普通任务下载的事件监听器
*/
class DownloadListener extends BaseListener<DownloadEntity, DownloadTask>
class DownloadListener extends BaseDListener<DownloadEntity, DownloadTask>
implements IDownloadListener {
DownloadListener(DownloadTask task, Handler outHandler) {
super(task, outHandler);

@ -139,14 +139,12 @@ public class DownloadTask extends AbsNormalTask<DownloadEntity> {
* 取消下载
*/
@Override public void cancel() {
if (!mEntity.isComplete()) {
if (!mUtil.isRunning()) {
if (mOutHandler != null) {
mOutHandler.obtainMessage(ISchedulers.CANCEL, this).sendToTarget();
}
if (!mUtil.isRunning()) {
if (mOutHandler != null) {
mOutHandler.obtainMessage(ISchedulers.CANCEL, this).sendToTarget();
}
mUtil.cancel();
}
mUtil.cancel();
}
public static class Builder {

@ -37,7 +37,6 @@ class HttpFileInfoThread implements Runnable {
private int mConnectTimeOut;
private OnFileInfoCallback onFileInfoListener;
HttpFileInfoThread(DownloadTaskEntity taskEntity, OnFileInfoCallback callback) {
this.mTaskEntity = taskEntity;
mEntity = taskEntity.getEntity();
@ -73,7 +72,8 @@ class HttpFileInfoThread implements Runnable {
private void handleConnect(HttpURLConnection conn) throws IOException {
long len = conn.getContentLength();
if (len < 0) {
len = Long.parseLong(conn.getHeaderField(mTaskEntity.contentLength));
String temp = conn.getHeaderField(mTaskEntity.contentLength);
len = TextUtils.isEmpty(temp) ? -1 : Long.parseLong(temp);
}
int code = conn.getResponseCode();
boolean isComplete = false;

@ -16,7 +16,6 @@
package com.arialyy.aria.core.download.downloader;
import android.util.Log;
import com.arialyy.aria.core.common.IUtil;
import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.core.inf.AbsTaskEntity;
@ -71,7 +70,6 @@ public class SimpleDownloadUtil implements IUtil, Runnable {
* 多线程断点续传下载文件开始下载
*/
@Override public void start() {
mListener.onPre();
new Thread(this).start();
}
@ -84,11 +82,11 @@ public class SimpleDownloadUtil implements IUtil, Runnable {
}
private void failDownload(String msg) {
Log.e(TAG, msg);
mListener.onFail();
}
@Override public void run() {
mListener.onPre();
if (mTaskEntity.getEntity().getFileSize() <= 1) {
new Thread(createInfoThread()).start();
} else {

@ -153,7 +153,7 @@ public abstract class AbsTarget<TARGET extends AbsTarget, ENTITY extends AbsEnti
}
/**
* 开始下载
* 开始任务
*/
@Override public void start() {
AriaManager.getInstance(AriaManager.APP)
@ -162,7 +162,7 @@ public abstract class AbsTarget<TARGET extends AbsTarget, ENTITY extends AbsEnti
}
/**
* 停止下载
* 停止任务
*
* @see #stop()
*/
@ -177,7 +177,7 @@ public abstract class AbsTarget<TARGET extends AbsTarget, ENTITY extends AbsEnti
}
/**
* 恢复下载
* 恢复任务
*/
@Override public void resume() {
AriaManager.getInstance(AriaManager.APP)
@ -186,7 +186,7 @@ public abstract class AbsTarget<TARGET extends AbsTarget, ENTITY extends AbsEnti
}
/**
* 取消下载
* 删除任务
*/
@Override public void cancel() {
AriaManager.getInstance(AriaManager.APP)
@ -194,6 +194,19 @@ public abstract class AbsTarget<TARGET extends AbsTarget, ENTITY extends AbsEnti
.exe();
}
/**
* 删除任务
*
* @param removeFile {@code true} 不仅删除任务数据库记录还会删除已经删除完成的文件
* {@code false}如果任务已经完成只删除任务数据库记录
*/
public void cancel(boolean removeFile) {
mTaskEntity.removeFile = removeFile;
AriaManager.getInstance(AriaManager.APP)
.setCmd(CommonUtil.createCmd(mTargetName, mTaskEntity, NormalCmdFactory.TASK_CANCEL))
.exe();
}
/**
* 创建文件名如果url链接有后缀名则使用url中的后缀名
*

@ -24,37 +24,37 @@ public interface IReceiver<ENTITY extends IEntity> {
/**
* Receiver 销毁
*/
public void destroy();
void destroy();
/**
* 移除事件回调
*/
public void removeSchedulerListener();
void removeSchedulerListener();
/**
* 移除观察者
*/
public void unRegister();
void unRegister();
/**
* 停止所有任务
*/
public void stopAllTask();
void stopAllTask();
/**
* 删除所有任务
*/
public void removeAllTask(boolean removeFile);
void removeAllTask(boolean removeFile);
/**
* 任务是否存在
*
* @param key 下载时为下载路径上传时为文件路径
*/
public boolean taskExists(String key);
boolean taskExists(String key);
/**
* 获取任务列表
*/
public List<ENTITY> getSimpleTaskList();
List<ENTITY> getSimpleTaskList();
}

@ -23,8 +23,4 @@ import com.arialyy.aria.core.inf.IEventListener;
*/
public interface IUploadListener extends IEventListener {
/**
* 上传完成服务器返回的状态码
*/
void onComplete(int state);
}

@ -25,45 +25,45 @@ public interface ISchedulerListener<TASK extends ITask> {
* 预处理有时有些地址链接比较慢这时可以先在这个地方出来一些界面上的UI如按钮的状态
* 在这个回调中任务是获取不到文件大小下载速度等参数
*/
public void onPre(TASK task);
void onPre(TASK task);
/**
* 任务预加载完成
*/
public void onTaskPre(TASK task);
void onTaskPre(TASK task);
/**
* 任务恢复下载
*/
public void onTaskResume(TASK task);
void onTaskResume(TASK task);
/**
* 任务开始
*/
public void onTaskStart(TASK task);
void onTaskStart(TASK task);
/**
* 任务停止
*/
public void onTaskStop(TASK task);
void onTaskStop(TASK task);
/**
* 任务取消
*/
public void onTaskCancel(TASK task);
void onTaskCancel(TASK task);
/**
* 任务下载失败
*/
public void onTaskFail(TASK task);
void onTaskFail(TASK task);
/**
* 任务完成
*/
public void onTaskComplete(TASK task);
void onTaskComplete(TASK task);
/**
* 任务执行中
*/
public void onTaskRunning(TASK task);
void onTaskRunning(TASK task);
}

@ -0,0 +1,138 @@
/*
* 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.os.Handler;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.inf.AbsEntity;
import com.arialyy.aria.core.inf.AbsTask;
import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.inf.IUploadListener;
import com.arialyy.aria.core.scheduler.ISchedulers;
import com.arialyy.aria.util.CommonUtil;
import java.lang.ref.WeakReference;
/**
* 下载监听类
*/
class BaseUListener<ENTITY extends AbsEntity, TASK extends AbsTask<ENTITY>>
implements IUploadListener {
private WeakReference<Handler> outHandler;
private long mLastLen = 0; //上一次发送长度
private boolean isFirst = true;
protected ENTITY mEntity;
protected TASK mTask;
private boolean isConvertSpeed = false;
boolean isWait = false;
BaseUListener(TASK task, Handler outHandler) {
this.outHandler = new WeakReference<>(outHandler);
this.mTask = new WeakReference<>(task).get();
this.mEntity = this.mTask.getEntity();
final AriaManager manager = AriaManager.getInstance(AriaManager.APP);
isConvertSpeed = manager.getDownloadConfig().isConvertSpeed();
mLastLen = mEntity.getCurrentProgress();
}
@Override public void onPre() {
saveData(IEntity.STATE_PRE, -1);
sendInState2Target(ISchedulers.PRE);
}
@Override public void onStart(long startLocation) {
saveData(IEntity.STATE_RUNNING, startLocation);
sendInState2Target(ISchedulers.START);
}
@Override public void onResume(long resumeLocation) {
saveData(IEntity.STATE_RUNNING, resumeLocation);
sendInState2Target(ISchedulers.RESUME);
}
@Override public void onProgress(long currentLocation) {
mEntity.setCurrentProgress(currentLocation);
long speed = currentLocation - mLastLen;
if (isFirst) {
speed = 0;
isFirst = false;
}
handleSpeed(speed);
sendInState2Target(ISchedulers.RUNNING);
mLastLen = currentLocation;
}
@Override public void onStop(long stopLocation) {
saveData(isWait ? IEntity.STATE_WAIT : IEntity.STATE_STOP, stopLocation);
handleSpeed(0);
sendInState2Target(ISchedulers.STOP);
}
@Override public void onCancel() {
saveData(IEntity.STATE_CANCEL, -1);
handleSpeed(0);
sendInState2Target(ISchedulers.CANCEL);
}
@Override public void onComplete() {
saveData(IEntity.STATE_COMPLETE, mEntity.getFileSize());
handleSpeed(0);
sendInState2Target(ISchedulers.COMPLETE);
}
@Override public void onFail() {
mEntity.setFailNum(mEntity.getFailNum() + 1);
saveData(IEntity.STATE_FAIL, mEntity.getCurrentProgress());
handleSpeed(0);
sendInState2Target(ISchedulers.FAIL);
}
private void handleSpeed(long speed) {
if (isConvertSpeed) {
mEntity.setConvertSpeed(CommonUtil.formatFileSize(speed < 0 ? 0 : speed) + "/s");
} else {
mEntity.setSpeed(speed < 0 ? 0 : speed);
}
}
/**
* 将任务状态发送给下载器
*
* @param state {@link ISchedulers#START}
*/
private void sendInState2Target(int state) {
if (outHandler.get() != null) {
outHandler.get().obtainMessage(state, mTask).sendToTarget();
}
}
private void saveData(int state, long location) {
mEntity.setComplete(state == IEntity.STATE_COMPLETE);
if (state == IEntity.STATE_CANCEL) {
mEntity.deleteData();
} else if (state == IEntity.STATE_COMPLETE) {
mEntity.setState(state);
mEntity.setCompleteTime(System.currentTimeMillis());
mEntity.setCurrentProgress(mEntity.getFileSize());
mEntity.update();
} else {
mEntity.setState(state);
if (location != -1) {
mEntity.setCurrentProgress(location);
}
mEntity.update();
}
}
}

@ -52,8 +52,4 @@ class UploadListener implements IUploadListener {
@Override public void onFail() {
}
@Override public void onComplete(int state) {
}
}

@ -35,7 +35,7 @@ import java.util.Set;
* 上传功能接收器
*/
public class UploadReceiver extends AbsReceiver<UploadEntity> {
private static final String TAG = "DownloadReceiver";
private static final String TAG = "UploadReceiver";
public ISchedulerListener<UploadTask> listener;
/**
@ -62,7 +62,6 @@ public class UploadReceiver extends AbsReceiver<UploadEntity> {
* 通过上传路径获取上传实体
*/
public UploadEntity getUploadEntity(String filePath) {
CheckUtil.checkUploadPath(filePath);
return DbEntity.findFirst(UploadEntity.class, "filePath=?", filePath);
}

@ -39,6 +39,7 @@ public class UploadTarget extends AbsUploadTarget<UploadTarget, UploadEntity, Up
if (mTaskEntity.entity == null) {
mTaskEntity.entity = getUploadEntity(filePath);
}
mEntity = mTaskEntity.entity;
File file = new File(filePath);
mEntity.setFileSize(file.length());
mEntity = mTaskEntity.entity;

@ -35,11 +35,11 @@ import org.apache.commons.net.ftp.FTPReply;
/**
* Created by Aria.Lao on 2017/7/28.
* FTP 单线程下载器
* FTP 单线程上传任务需要FTP 服务器给用户打开删除和读入IO的权限
*/
class FtpThreadTask extends AbsThreadTask<UploadEntity, UploadTaskEntity> {
private final String TAG = "FtpThreadTask";
private String remotePath, charSet;
private String dir, remotePath, charSet;
FtpThreadTask(StateConstance constance, IEventListener listener,
SubThreadConfig<UploadTaskEntity> info) {
@ -64,8 +64,8 @@ class FtpThreadTask extends AbsThreadTask<UploadEntity, UploadTaskEntity> {
mChildCurrentLocation = mConfig.START_LOCATION;
client = createClient();
if (client == null) return;
client.makeDirectory(remotePath);
client.changeWorkingDirectory(remotePath);
client.makeDirectory(dir);
client.changeWorkingDirectory(dir);
client.setRestartOffset(mConfig.START_LOCATION);
file = new BufferedRandomAccessFile(mConfig.TEMP_FILE, "rwd", mBufSize);
file.seek(mConfig.START_LOCATION);
@ -154,9 +154,8 @@ class FtpThreadTask extends AbsThreadTask<UploadEntity, UploadTaskEntity> {
String[] pp = url.split("/")[2].split(":");
String serverIp = pp[0];
int port = Integer.parseInt(pp[1]);
remotePath = url.substring(url.indexOf(pp[1]) + pp[1].length(), url.length())
+ "/"
+ mEntity.getFileName();
dir = url.substring(url.indexOf(pp[1]) + pp[1].length(), url.length());
remotePath = dir + "/" + mEntity.getFileName();
FTPClient client = new FTPClient();
client.connect(serverIp, port);
if (!TextUtils.isEmpty(mTaskEntity.account)) {

@ -49,7 +49,7 @@ class HttpThreadTask extends AbsThreadTask<UploadEntity, UploadTaskEntity> {
private long mCurrentLocation = 0;
private OutputStream mOutputStream;
public HttpThreadTask(StateConstance constance, IUploadListener listener,
HttpThreadTask(StateConstance constance, IUploadListener listener,
SubThreadConfig<UploadTaskEntity> uploadInfo) {
super(constance, listener, uploadInfo);
}
@ -89,7 +89,6 @@ class HttpThreadTask extends AbsThreadTask<UploadEntity, UploadTaskEntity> {
for (String key : keys) {
addFormField(writer, key, mTaskEntity.formFields.get(key));
}
mListener.onStart(0);
uploadFile(writer, mTaskEntity.attachment, uploadFile);
Log.d(TAG, finish(writer) + "");
} catch (IOException e) {
@ -101,6 +100,7 @@ class HttpThreadTask extends AbsThreadTask<UploadEntity, UploadTaskEntity> {
private void fail() {
try {
mListener.onFail();
STATE.isRunning = false;
if (mOutputStream != null) {
mOutputStream.close();
}
@ -167,9 +167,11 @@ class HttpThreadTask extends AbsThreadTask<UploadEntity, UploadTaskEntity> {
writer.flush();
if (STATE.isCancel) {
mListener.onCancel();
STATE.isRunning = false;
return;
}
mListener.onComplete();
STATE.isRunning = false;
}
/**
@ -195,7 +197,7 @@ class HttpThreadTask extends AbsThreadTask<UploadEntity, UploadTaskEntity> {
mHttpConn.disconnect();
} else {
Log.w(TAG, "state_code = " + status);
mListener.onFail();
fail();
}
writer.flush();

@ -23,17 +23,17 @@ import com.arialyy.aria.util.CheckUtil;
/**
* Created by lyy on 2017/2/9.
* 简单的http文件上传工具
* 简单的文件上传工具
*/
public class SimpleHttpUploadUtil implements IUtil, Runnable {
private static final String TAG = "SimpleHttpUploadUtil";
public class SimpleUploadUtil implements IUtil, Runnable {
private static final String TAG = "SimpleUploadUtil";
private UploadEntity mUploadEntity;
private UploadTaskEntity mTaskEntity;
private IUploadListener mListener;
private Uploader mUploader;
public SimpleHttpUploadUtil(UploadTaskEntity taskEntity, IUploadListener listener) {
public SimpleUploadUtil(UploadTaskEntity taskEntity, IUploadListener listener) {
mTaskEntity = taskEntity;
CheckUtil.checkTaskEntity(taskEntity);
mUploadEntity = taskEntity.getEntity();
@ -45,6 +45,7 @@ public class SimpleHttpUploadUtil implements IUtil, Runnable {
}
@Override public void run() {
mListener.onPre();
mUploader.start();
}
@ -69,7 +70,7 @@ public class SimpleHttpUploadUtil implements IUtil, Runnable {
}
@Override public void start() {
mUploader.start();
new Thread(this).start();
}
@Override public void resume() {

@ -47,14 +47,14 @@ class Uploader extends AbsFileer<UploadEntity, UploadTaskEntity> {
* 5不支持断点则是新任务
*/
protected void checkTask() {
if (!mTaskEntity.isSupportBP) {
isNewTask = true;
return;
}
mConfigFile = new File(mContext.getFilesDir().getPath()
+ AriaManager.UPLOAD_TEMP_DIR
+ mEntity.getFileName()
+ ".properties");
if (!mTaskEntity.isSupportBP) {
isNewTask = true;
return;
}
if (!mConfigFile.exists()) { //记录文件被删除,则重新下载
isNewTask = true;
CommonUtil.createFile(mConfigFile.getPath());
@ -70,7 +70,7 @@ class Uploader extends AbsFileer<UploadEntity, UploadTaskEntity> {
}
@Override protected int getThreadNum() {
@Override protected int getNewTaskThreadNum() {
return 1;
}

@ -150,7 +150,7 @@ public class CommonUtil {
/**
* 删除上传任务的配置包括
*
* @param removeFile {@code true} 不仅删除任务数据库记录还会删除已经下载完成的文件
* @param removeFile {@code true} 不仅删除任务数据库记录还会删除已经删除完成的文件
* {@code false}如果任务已经完成只删除任务数据库记录
*/
public static void delUploadTaskConfig(boolean removeFile, UploadTaskEntity tEntity) {
@ -160,15 +160,8 @@ public class CommonUtil {
if (file.exists()) {
file.delete();
}
} else {
if (!uEntity.isComplete()) {
if (file.exists()) {
file.delete();
}
}
}
File config = new File(
AriaManager.APP.getFilesDir().getPath() + "/temp/" + uEntity.getFileName() + ".properties");
File config = new File(getFileConfig(false, uEntity.getFileName()));
if (config.exists()) {
config.delete();
}
@ -197,8 +190,7 @@ public class CommonUtil {
}
}
File config = new File(
AriaManager.APP.getFilesDir().getPath() + "/temp/" + dEntity.getFileName() + ".properties");
File config = new File(getFileConfig(true, dEntity.getFileName()));
if (config.exists()) {
config.delete();
}

@ -44,18 +44,12 @@ import java.lang.annotation.Target;
}
/**
* 如果你在方法中添加{@code @Upload.onTaskPre}注解在任务预处理完成Aria会调用该方法
* 如果你在方法中添加{@code @Upload.onTaskResume}注解在任务恢复下载Aria会调用该方法
*/
@Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskPre {
@Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskResume {
String[] value() default { AriaConstance.NO_URL };
}
/**
* 如果你在方法中添加{@code @Upload.onTaskResume}注解在任务恢复下载时Aria会调用该方法
*/
//@Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskResume {
//}
/**
* 如果你在方法中添加{@code @Upload.onTaskStart}注解在任务开始下载时Aria会调用该方法
*/
@ -101,8 +95,7 @@ import java.lang.annotation.Target;
/**
* 如果你在方法中添加{@code @Upload.onNoSupportBreakPoint}注解如果该任务不支持断点Aria会调用该方法
*/
@Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD)
@interface onNoSupportBreakPoint {
@Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onNoSupportBreakPoint {
String[] value() default { AriaConstance.NO_URL };
}
}

@ -70,8 +70,7 @@ import javax.lang.model.element.TypeElement;
annotataions.add(Upload.onTaskCancel.class.getCanonicalName());
annotataions.add(Upload.onTaskComplete.class.getCanonicalName());
annotataions.add(Upload.onTaskFail.class.getCanonicalName());
annotataions.add(Upload.onTaskPre.class.getCanonicalName());
//annotataions.add(Upload.onTaskResume.class.getCanonicalName());
annotataions.add(Upload.onTaskResume.class.getCanonicalName());
annotataions.add(Upload.onTaskRunning.class.getCanonicalName());
annotataions.add(Upload.onTaskStart.class.getCanonicalName());
annotataions.add(Upload.onTaskStop.class.getCanonicalName());

@ -120,8 +120,7 @@ class ElementHandler {
saveMethod(TaskEnum.UPLOAD, roundEnv, Upload.onTaskComplete.class,
ProxyConstance.TASK_COMPLETE);
saveMethod(TaskEnum.UPLOAD, roundEnv, Upload.onTaskFail.class, ProxyConstance.TASK_FAIL);
saveMethod(TaskEnum.UPLOAD, roundEnv, Upload.onTaskPre.class, ProxyConstance.TASK_PRE);
//saveMethod(false, roundEnv, Upload.onTaskResume.class);
saveMethod(TaskEnum.UPLOAD, roundEnv, Upload.onTaskResume.class, ProxyConstance.TASK_RESUME);
saveMethod(TaskEnum.UPLOAD, roundEnv, Upload.onTaskRunning.class, ProxyConstance.TASK_RUNNING);
saveMethod(TaskEnum.UPLOAD, roundEnv, Upload.onTaskStart.class, ProxyConstance.TASK_START);
saveMethod(TaskEnum.UPLOAD, roundEnv, Upload.onTaskStop.class, ProxyConstance.TASK_STOP);
@ -484,10 +483,10 @@ class ElementHandler {
values = method.getAnnotation(Upload.onPre.class).value();
break;
case ProxyConstance.TASK_PRE:
values = method.getAnnotation(Upload.onTaskPre.class).value();
//values = method.getAnnotation(Upload.onTaskPre.class).value();
break;
case ProxyConstance.TASK_RESUME:
//values = method.getAnnotation(Upload.onTaskResume.class).value();
values = method.getAnnotation(Upload.onTaskResume.class).value();
break;
case ProxyConstance.TASK_START:
values = method.getAnnotation(Upload.onTaskStart.class).value();

@ -1,24 +0,0 @@
package com.arialyy.ftpplug;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumentation test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class) public class ExampleInstrumentedTest {
@Test public void useAppContext() throws Exception {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("com.arialyy.ftpplug.test", appContext.getPackageName());
}
}

@ -1,8 +0,0 @@
package com.arialyy.ftpplug;
/**
* Created by Aria.Lao on 2017/7/24.
*/
public class Test {
}

@ -1,16 +0,0 @@
package com.arialyy.ftpplug;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test public void addition_isCorrect() throws Exception {
assertEquals(4, 2 + 2);
}
}

1
app/.gitignore vendored

@ -1 +1,2 @@
/build
*.log

@ -24,7 +24,6 @@
</activity>
<activity android:name=".download.DownloadActivity"/>
<activity android:name=".upload.UploadActivity"/>
<activity android:name=".download.SingleTaskActivity"/>
<activity android:name=".download.multi_download.MultiTaskActivity"/>
<activity android:name=".download.fragment_download.FragmentActivity"/>
@ -34,6 +33,7 @@
<activity android:name=".download.group.DownloadGroupActivity"/>
<activity android:name=".download.FtpDownloadActivity"/>
<activity android:name=".download.group.FTPDirDownloadActivity"/>
<activity android:name=".upload.HttpUploadActivity"/>
<activity android:name=".upload.FtpUploadActivity"/>
<service android:name=".download.service_download.DownloadService"/>

@ -37,6 +37,8 @@
</download>
<upload>
<!--是否需要转换速度单位,转换完成后为:1b/s、1kb/s、1mb/s、1gb/s、1tb/s,如果不需要将返回byte长度-->
<convertSpeed value="true"/>
<!--设置上传队列最大任务数, 默认为2-->
<maxTaskNum value="2"/>

@ -27,7 +27,7 @@ import com.arialyy.simple.download.FtpDownloadActivity;
import com.arialyy.simple.download.group.DownloadGroupActivity;
import com.arialyy.simple.download.group.FTPDirDownloadActivity;
import com.arialyy.simple.upload.FtpUploadActivity;
import com.arialyy.simple.upload.UploadActivity;
import com.arialyy.simple.upload.HttpUploadActivity;
/**
* Created by Aria.Lao on 2017/3/1.
@ -54,7 +54,7 @@ public class MainActivity extends BaseActivity<ActivityMainBinding> {
startActivity(new Intent(this, DownloadActivity.class));
break;
case R.id.upload:
startActivity(new Intent(this, UploadActivity.class));
startActivity(new Intent(this, HttpUploadActivity.class));
break;
case R.id.download_task_group:
startActivity(new Intent(this, DownloadGroupActivity.class));

@ -185,17 +185,6 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
public void onClick(View view) {
switch (view.getId()) {
case R.id.start:
//String text = ((TextView) view).getText().toString();
//if (text.equals("重新开始?") || text.equals("开始")) {
// Aria.download(this)
// .load(URL)
// .addHeader("groupName", "value")
// .setDownloadPath(Environment.getExternalStorageDirectory().getPath() + "/test.apk")
// .setFileName("hehe.apk")
// .start();
//} else if (text.equals("恢复")) {
// Aria.download(this).load(URL).resume();
//}
Aria.download(this)
.load(DOWNLOAD_URL)
.addHeader("groupName", "value")

@ -20,7 +20,9 @@ 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.show.L;
import com.arialyy.frame.util.show.T;
import com.arialyy.simple.R;
@ -32,12 +34,19 @@ import com.arialyy.simple.databinding.ActivityFtpUploadBinding;
* Ftp 文件上传demo
*/
public class FtpUploadActivity extends BaseActivity<ActivityFtpUploadBinding> {
private final String FILE_PATH = "/mnt/sdcard/王者军团.apk";
private final String FILE_PATH = "/mnt/sdcard/gggg.apk";
private final String URL = "ftp://172.18.104.129:21/upload/";
@Override protected void init(Bundle savedInstanceState) {
setTile("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() {
@ -53,7 +62,7 @@ public class FtpUploadActivity extends BaseActivity<ActivityFtpUploadBinding> {
Aria.upload(this).loadFtp(FILE_PATH).stop();
break;
case R.id.cancel:
Aria.upload(this).load(FILE_PATH).cancel();
Aria.upload(this).loadFtp(FILE_PATH).cancel();
break;
}
}
@ -62,12 +71,12 @@ public class FtpUploadActivity extends BaseActivity<ActivityFtpUploadBinding> {
getBinding().setFileSize(task.getConvertFileSize());
}
@Upload.onTaskPre public void taskPre(UploadTask task) {
L.d(TAG, "fileSize = " + task.getConvertFileSize());
}
@Upload.onTaskStart public void taskStart(UploadTask task) {
Log.d(TAG, "开始上传");
}
@Upload.onTaskResume public void taskResume(UploadTask task) {
Log.d(TAG, "恢复上传");
}
@Upload.onTaskStop public void taskStop(UploadTask task) {
@ -77,7 +86,9 @@ public class FtpUploadActivity extends BaseActivity<ActivityFtpUploadBinding> {
@Upload.onTaskCancel public void taskCancel(UploadTask task) {
getBinding().setSpeed("");
Log.d(TAG, "取消上传");
getBinding().setFileSize("");
getBinding().setProgress(0);
Log.d(TAG, "删除任务");
}
@Upload.onTaskRunning public void taskRunning(UploadTask task) {

@ -17,16 +17,12 @@
package com.arialyy.simple.upload;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import butterknife.Bind;
import butterknife.OnClick;
import com.arialyy.annotations.Upload;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.upload.UploadTask;
import com.arialyy.frame.util.FileUtil;
import com.arialyy.frame.util.show.L;
import com.arialyy.frame.util.show.T;
import com.arialyy.simple.R;
import com.arialyy.simple.base.BaseActivity;
import com.arialyy.simple.databinding.ActivityUploadBinding;
@ -35,50 +31,19 @@ import com.arialyy.simple.widget.HorizontalProgressBarWithNumber;
/**
* Created by Aria.Lao on 2017/2/9.
*/
public class UploadActivity extends BaseActivity<ActivityUploadBinding> {
private static final String TAG = "UploadActivity";
public class HttpUploadActivity extends BaseActivity<ActivityUploadBinding> {
private static final String TAG = "HttpUploadActivity";
@Bind(R.id.pb) HorizontalProgressBarWithNumber mPb;
private static final int START = 0;
private static final int STOP = 1;
private static final int CANCEL = 2;
private static final int RUNNING = 3;
private static final int COMPLETE = 4;
private static final String FILE_PATH = "/sdcard/Download/test.zip";
private Handler mHandler = new Handler() {
@Override public void handleMessage(Message msg) {
super.handleMessage(msg);
UploadTask task = (UploadTask) msg.obj;
switch (msg.what) {
case START:
getBinding().setFileSize(FileUtil.formatFileSize(task.getFileSize()));
break;
case STOP:
mPb.setProgress(0);
break;
case CANCEL:
mPb.setProgress(0);
break;
case RUNNING:
int p = (int) (task.getCurrentProgress() * 100 / task.getFileSize());
mPb.setProgress(p);
break;
case COMPLETE:
T.showShort(UploadActivity.this, "上传完成");
mPb.setProgress(100);
break;
}
}
};
private static final String FILE_PATH = "/sdcard/large.rar";
@Override protected int setLayoutId() {
return R.layout.activity_upload;
}
@Override protected void init(Bundle savedInstanceState) {
setTile("HTTP 上传");
super.init(savedInstanceState);
setTile("http上传");
Aria.upload(this).register();
}
@ -101,27 +66,31 @@ public class UploadActivity extends BaseActivity<ActivityUploadBinding> {
@Upload.onPre public void onPre(UploadTask task) {
}
@Upload.onTaskPre public void taskPre(UploadTask task) {
L.d(TAG, "fileSize = " + task.getConvertFileSize());
}
@Upload.onTaskStart public void taskStart(UploadTask task) {
mHandler.obtainMessage(START, task).sendToTarget();
L.d(TAG, "upload start");
getBinding().setFileSize(task.getConvertFileSize());
}
@Upload.onTaskStop public void taskStop(UploadTask task) {
mHandler.obtainMessage(STOP, task).sendToTarget();
L.d(TAG, "upload stop");
getBinding().setSpeed("");
getBinding().setProgress(0);
}
@Upload.onTaskCancel public void taskCancel(UploadTask task) {
mHandler.obtainMessage(CANCEL, task).sendToTarget();
L.d(TAG, "upload cancel");
getBinding().setSpeed("");
getBinding().setProgress(0);
}
@Upload.onTaskRunning public void taskRunning(UploadTask task) {
mHandler.obtainMessage(RUNNING, task).sendToTarget();
getBinding().setSpeed(task.getConvertSpeed());
getBinding().setProgress(task.getPercent());
}
@Upload.onTaskComplete public void taskComplete(UploadTask task) {
mHandler.obtainMessage(COMPLETE, task).sendToTarget();
L.d(TAG, "上传完成");
getBinding().setSpeed("");
getBinding().setProgress(100);
}
}

@ -13,7 +13,7 @@
android:id="@+id/download"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="下载"
android:text="http 下载"
style="?buttonBarButtonStyle"
/>
@ -21,7 +21,7 @@
android:id="@+id/upload"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="上传"
android:text="http 上传"
style="?buttonBarButtonStyle"
/>
@ -29,7 +29,7 @@
android:id="@+id/download_task_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="下载任务组"
android:text="http 下载任务组"
style="?buttonBarButtonStyle"
/>

@ -11,6 +11,11 @@
type="String"
/>
<variable
name="progress"
type="int"
/>
</data>
<LinearLayout
@ -34,6 +39,7 @@
android:layout_margin="16dp"
android:layout_toLeftOf="@+id/size"
android:max="100"
android:progress="@{progress}"
style="?android:attr/progressBarStyleHorizontal"
/>

@ -15,16 +15,12 @@
*/
package com.arialyy.aria.core.upload;
import android.content.Context;
import android.os.Handler;
import android.util.Log;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.inf.AbsNormalTask;
import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.scheduler.ISchedulers;
import com.arialyy.aria.core.upload.uploader.SimpleHttpUploadUtil;
import com.arialyy.aria.util.CommonUtil;
import java.lang.ref.WeakReference;
import com.arialyy.aria.core.upload.uploader.SimpleUploadUtil;
/**
* Created by lyy on 2017/2/23.
@ -33,14 +29,14 @@ import java.lang.ref.WeakReference;
public class UploadTask extends AbsNormalTask<UploadEntity> {
private static final String TAG = "UploadTask";
private SimpleHttpUploadUtil mUtil;
private UListener mListener;
private SimpleUploadUtil mUtil;
private BaseUListener<UploadEntity, UploadTask> mListener;
private UploadTask(UploadTaskEntity taskEntity, Handler outHandler) {
mOutHandler = outHandler;
mEntity = taskEntity.getEntity();
mListener = new UListener(mOutHandler, this);
mUtil = new SimpleHttpUploadUtil(taskEntity, mListener);
mListener = new BaseUListener<>(this, mOutHandler);
mUtil = new SimpleUploadUtil(taskEntity, mListener);
}
@Override public String getKey() {
@ -55,9 +51,6 @@ public class UploadTask extends AbsNormalTask<UploadEntity> {
if (mUtil.isRunning()) {
Log.d(TAG, "任务正在下载");
} else {
if (mListener == null) {
mListener = new UploadTask.UListener(mOutHandler, this);
}
mUtil.start();
}
}
@ -75,119 +68,12 @@ public class UploadTask extends AbsNormalTask<UploadEntity> {
}
@Override public void cancel() {
if (!mEntity.isComplete()) {
// 如果任务不是下载状态
mUtil.cancel();
mEntity.deleteData();
if (!mUtil.isRunning()) {
if (mOutHandler != null) {
mOutHandler.obtainMessage(ISchedulers.CANCEL, this).sendToTarget();
}
}
}
private static class UListener extends UploadListener {
WeakReference<Handler> outHandler;
WeakReference<UploadTask> task;
long lastLen = 0; //上一次发送长度
long lastTime = 0;
long INTERVAL_TIME = 1000; //1m更新周期
boolean isFirst = true;
UploadEntity entity;
boolean isConvertSpeed = false;
Context context;
UListener(Handler outHandle, UploadTask task) {
this.outHandler = new WeakReference<>(outHandle);
this.task = new WeakReference<>(task);
entity = this.task.get().getEntity();
context = AriaManager.APP;
final AriaManager manager = AriaManager.getInstance(context);
isConvertSpeed = manager.getUploadConfig().isConvertSpeed();
}
@Override public void onPre() {
sendInState2Target(ISchedulers.PRE);
saveData(IEntity.STATE_PRE, -1);
}
@Override public void onStart(long startLocation) {
sendInState2Target(ISchedulers.START);
saveData(IEntity.STATE_RUNNING, 0);
}
@Override public void onResume(long resumeLocation) {
sendInState2Target(ISchedulers.RESUME);
saveData(IEntity.STATE_RUNNING, resumeLocation);
}
@Override public void onStop(long stopLocation) {
handleSpeed(0);
sendInState2Target(ISchedulers.STOP);
saveData(IEntity.STATE_STOP, stopLocation);
}
@Override public void onProgress(long currentLocation) {
if (System.currentTimeMillis() - lastTime > INTERVAL_TIME) {
long speed = currentLocation - lastLen;
lastTime = System.currentTimeMillis();
if (isFirst) {
speed = 0;
isFirst = false;
}
handleSpeed(speed);
entity.setCurrentProgress(currentLocation);
lastLen = currentLocation;
sendInState2Target(ISchedulers.RUNNING);
}
}
@Override public void onCancel() {
handleSpeed(0);
sendInState2Target(ISchedulers.CANCEL);
saveData(IEntity.STATE_CANCEL, -1);
entity.deleteData();
}
@Override public void onComplete() {
entity.setComplete(true);
handleSpeed(0);
sendInState2Target(ISchedulers.COMPLETE);
saveData(IEntity.STATE_COMPLETE, entity.getFileSize());
}
@Override public void onFail() {
entity.setFailNum(entity.getFailNum() + 1);
handleSpeed(0);
sendInState2Target(ISchedulers.FAIL);
saveData(IEntity.STATE_FAIL, -1);
}
private void handleSpeed(long speed) {
if (isConvertSpeed) {
entity.setConvertSpeed(CommonUtil.formatFileSize(speed) + "/s");
} else {
entity.setSpeed(speed);
}
}
/**
* 将任务状态发送给下载器
*
* @param state {@link ISchedulers#START}
*/
private void sendInState2Target(int state) {
if (outHandler.get() != null) {
outHandler.get().obtainMessage(state, task.get()).sendToTarget();
}
}
private void saveData(int state, long location) {
entity.setState(state);
entity.setComplete(state == IEntity.STATE_COMPLETE);
entity.setCurrentProgress(location);
entity.update();
}
mUtil.cancel();
}
public static class Builder {

Loading…
Cancel
Save