diff --git a/.idea/misc.xml b/.idea/misc.xml index fbb68289..5d199810 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -37,7 +37,7 @@ - + diff --git a/Aria/src/main/java/com/arialyy/aria/core/Aria.java b/Aria/src/main/java/com/arialyy/aria/core/Aria.java index b6f8cd2a..5272b2a8 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/Aria.java +++ b/Aria/src/main/java/com/arialyy/aria/core/Aria.java @@ -29,6 +29,7 @@ import android.widget.PopupWindow; import com.arialyy.aria.core.download.DownloadReceiver; import com.arialyy.aria.core.scheduler.OnSchedulerListener; import com.arialyy.aria.core.download.DownloadTask; +import com.arialyy.aria.core.upload.UploadTask; /** * Created by lyy on 2016/12/1. @@ -142,7 +143,48 @@ import com.arialyy.aria.core.download.DownloadTask; } } - public static class SimpleSchedulerListener implements OnSchedulerListener { + /** + * 上传任务状态监听 + */ + public static class UploadSchedulerListener implements OnSchedulerListener { + + @Override public void onTaskPre(UploadTask task) { + + } + + @Override public void onTaskResume(UploadTask task) { + + } + + @Override public void onTaskStart(UploadTask task) { + + } + + @Override public void onTaskStop(UploadTask task) { + + } + + @Override public void onTaskCancel(UploadTask task) { + + } + + @Override public void onTaskFail(UploadTask task) { + + } + + @Override public void onTaskComplete(UploadTask task) { + + } + + @Override public void onTaskRunning(UploadTask task) { + + } + } + + /** + * 下载任务状态监听 + */ + public static class DownloadSchedulerListener implements OnSchedulerListener { @Override public void onTaskPre(DownloadTask task) { diff --git a/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java b/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java index 5adc60ff..5d587e9d 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java +++ b/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java @@ -33,7 +33,6 @@ import com.arialyy.aria.core.download.DownloadReceiver; import com.arialyy.aria.core.inf.ICmd; import com.arialyy.aria.core.inf.IReceiver; import com.arialyy.aria.core.queue.DownloadTaskQueue; -import com.arialyy.aria.core.queue.ITaskQueue; import com.arialyy.aria.core.upload.UploadReceiver; import com.arialyy.aria.orm.DbEntity; import com.arialyy.aria.orm.DbUtil; @@ -56,9 +55,8 @@ import java.util.Map; private static final String UPLOAD = "_upload"; private static final Object LOCK = new Object(); @SuppressLint("StaticFieldLeak") private static volatile AriaManager INSTANCE = null; - Map mReceivers = new HashMap<>(); - private LifeCallback mLifeCallback; - DownloadTaskQueue mDTaskQueue; + private Map mReceivers = new HashMap<>(); + private DownloadTaskQueue mDTaskQueue; public static Context APP; private List mCommands = new ArrayList<>(); @@ -267,7 +265,7 @@ import java.util.Map; private void regAppLifeCallback(Context context) { Context app = context.getApplicationContext(); if (app instanceof Application) { - mLifeCallback = new LifeCallback(); + LifeCallback mLifeCallback = new LifeCallback(); ((Application) app).registerActivityLifecycleCallbacks(mLifeCallback); } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/AddCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/AddCmd.java index 40dfe878..f113fb8a 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/command/AddCmd.java +++ b/Aria/src/main/java/com/arialyy/aria/core/command/AddCmd.java @@ -29,7 +29,12 @@ class AddCmd extends IDownloadCmd { } @Override public void executeCmd() { - + // DownloadTask task = mQueue.getTask(mEntity.downloadEntity); + // if (task == null) { + // mQueue.createTask(mTargetName, mEntity); + // } else { + // Log.w(TAG, "添加命令执行失败,【该任务已经存在】"); + // } } //AddCmd(DownloadTaskEntity entity) { diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTask.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTask.java index 96a9d105..1dcc0454 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTask.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTask.java @@ -25,7 +25,7 @@ import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.inf.IEntity; import com.arialyy.aria.core.inf.ITask; import com.arialyy.aria.core.scheduler.DownloadSchedulers; -import com.arialyy.aria.core.scheduler.IDownloadSchedulers; +import com.arialyy.aria.core.scheduler.ISchedulers; import com.arialyy.aria.util.CheckUtil; import com.arialyy.aria.util.CommonUtil; import com.arialyy.aria.util.Configuration; @@ -179,14 +179,14 @@ public class DownloadTask implements ITask { } } - static class Builder { + public static class Builder { DownloadTaskEntity taskEntity; Handler outHandler; int threadNum = 3; String targetName; - Builder(String targetName, DownloadTaskEntity taskEntity) { + public Builder(String targetName, DownloadTaskEntity taskEntity) { CheckUtil.checkDownloadEntity(taskEntity.downloadEntity); this.targetName = targetName; this.taskEntity = taskEntity; @@ -195,9 +195,9 @@ public class DownloadTask implements ITask { /** * 设置自定义Handler处理下载状态时间 * - * @param schedulers {@link IDownloadSchedulers} + * @param schedulers {@link ISchedulers} */ - Builder setOutHandler(IDownloadSchedulers schedulers) { + public Builder setOutHandler(ISchedulers schedulers) { this.outHandler = new Handler(schedulers); return this; } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTaskFactory.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTaskFactory.java deleted file mode 100644 index c793b151..00000000 --- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTaskFactory.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.arialyy.aria.core.download; - -import android.content.Context; -import com.arialyy.aria.core.scheduler.IDownloadSchedulers; - -/** - * Created by lyy on 2016/8/18. - * 任务工厂 - */ -public class DownloadTaskFactory { - private static final String TAG = "DownloadTaskFactory"; - - private static final Object LOCK = new Object(); - private static volatile DownloadTaskFactory INSTANCE = null; - - private DownloadTaskFactory() { - - } - - public static DownloadTaskFactory getInstance() { - if (INSTANCE == null) { - synchronized (LOCK) { - INSTANCE = new DownloadTaskFactory(); - } - } - return INSTANCE; - } - - /** - * 创建普通下载任务 - * - * @param entity 下载任务实体{@link DownloadTaskEntity} - * @param schedulers {@link IDownloadSchedulers} - */ - public DownloadTask createTask(DownloadTaskEntity entity, IDownloadSchedulers schedulers) { - return createTask("", entity, schedulers); - } - - /** - * @param entity 下载任务实体{@link DownloadTaskEntity} - * @param schedulers {@link IDownloadSchedulers} - */ - public DownloadTask createTask(String targetName, DownloadTaskEntity entity, - IDownloadSchedulers schedulers) { - DownloadTask.Builder builder = new DownloadTask.Builder(targetName, entity); - builder.setOutHandler(schedulers); - return builder.build(); - } -} \ No newline at end of file diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/AbsTaskQueue.java b/Aria/src/main/java/com/arialyy/aria/core/queue/AbsTaskQueue.java index cf87acdf..a61b12fe 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/queue/AbsTaskQueue.java +++ b/Aria/src/main/java/com/arialyy/aria/core/queue/AbsTaskQueue.java @@ -1,6 +1,21 @@ +/* + * 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.queue; -import com.arialyy.aria.core.download.DownloadTask; import com.arialyy.aria.core.inf.IEntity; import com.arialyy.aria.core.inf.ITask; import com.arialyy.aria.core.inf.ITaskEntity; @@ -12,6 +27,6 @@ import com.arialyy.aria.core.queue.pool.ExecutePool; */ abstract class AbsTaskQueue implements ITaskQueue { - CachePool mCachePool = new CachePool<>(); - ExecutePool mExecutePool = new ExecutePool<>(); + CachePool mCachePool = new CachePool<>(); + ExecutePool mExecutePool = new ExecutePool<>(); } diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/DownloadTaskQueue.java b/Aria/src/main/java/com/arialyy/aria/core/queue/DownloadTaskQueue.java index f7a47ffe..7288fde6 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/queue/DownloadTaskQueue.java +++ b/Aria/src/main/java/com/arialyy/aria/core/queue/DownloadTaskQueue.java @@ -25,7 +25,6 @@ import com.arialyy.aria.core.inf.IEntity; import com.arialyy.aria.core.queue.pool.CachePool; import com.arialyy.aria.core.queue.pool.ExecutePool; import com.arialyy.aria.core.scheduler.DownloadSchedulers; -import com.arialyy.aria.core.download.DownloadTaskFactory; import com.arialyy.aria.util.Configuration; /** @@ -149,14 +148,14 @@ public class DownloadTaskQueue } @Override public DownloadTask createTask(String target, DownloadTaskEntity entity) { - DownloadTask task; - if (TextUtils.isEmpty(target)) { - task = DownloadTaskFactory.getInstance().createTask(entity, DownloadSchedulers.getInstance()); - } else { - task = DownloadTaskFactory.getInstance() + DownloadTask task = null; + if (!TextUtils.isEmpty(target)) { + task = (DownloadTask) TaskFactory.getInstance() .createTask(target, entity, DownloadSchedulers.getInstance()); + mCachePool.putTask(task); + } else { + Log.e(TAG, "target name 为 null是!!"); } - mCachePool.putTask(task); return task; } diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/ITaskQueue.java b/Aria/src/main/java/com/arialyy/aria/core/queue/ITaskQueue.java index 5820a789..0b9b18af 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/queue/ITaskQueue.java +++ b/Aria/src/main/java/com/arialyy/aria/core/queue/ITaskQueue.java @@ -22,6 +22,9 @@ import com.arialyy.aria.core.download.DownloadTask; import com.arialyy.aria.core.inf.IEntity; import com.arialyy.aria.core.inf.ITask; import com.arialyy.aria.core.inf.ITaskEntity; +import com.arialyy.aria.core.upload.UploadEntity; +import com.arialyy.aria.core.upload.UploadTask; +import com.arialyy.aria.core.upload.UploadTaskEntity; /** * Created by lyy on 2016/8/16. @@ -32,28 +35,28 @@ public interface ITaskQueue {@link DownloadTaskEntity}、{@link UploadTaskEntity} + * @param {@link DownloadSchedulers} + * @return {@link DownloadTask}、{@link UploadTask} + */ + ITask createTask( + String targetName, ENTITY entity, SCHEDULER schedulers) { + if (entity instanceof DownloadTaskEntity) { + return createDownloadTask(targetName, (DownloadTaskEntity) entity, schedulers); + } else if (entity instanceof UploadTaskEntity) { + return createUploadTask(targetName, (UploadTaskEntity) entity, schedulers); + } return null; + } + + /** + * @param entity 上传任务实体{@link UploadTaskEntity} + * @param schedulers {@link ISchedulers} + */ + private UploadTask createUploadTask(String targetName, UploadTaskEntity entity, + ISchedulers schedulers) { + UploadTask.Builder builder = new UploadTask.Builder(); + builder.setTargetName(targetName); + builder.setUploadTaskEntity(entity); + builder.setOutHandler(schedulers); + return builder.build(); + } + + /** + * @param entity 下载任务实体{@link DownloadTaskEntity} + * @param schedulers {@link ISchedulers} + */ + private DownloadTask createDownloadTask(String targetName, DownloadTaskEntity entity, + ISchedulers schedulers) { + DownloadTask.Builder builder = new DownloadTask.Builder(targetName, entity); + builder.setOutHandler(schedulers); + return builder.build(); + } +} \ No newline at end of file diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/UploadTaskQueue.java b/Aria/src/main/java/com/arialyy/aria/core/queue/UploadTaskQueue.java new file mode 100644 index 00000000..9b7c061a --- /dev/null +++ b/Aria/src/main/java/com/arialyy/aria/core/queue/UploadTaskQueue.java @@ -0,0 +1,120 @@ +/* + * 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.queue; + +import android.text.TextUtils; +import android.util.Log; +import com.arialyy.aria.core.scheduler.UploadSchedulers; +import com.arialyy.aria.core.upload.UploadEntity; +import com.arialyy.aria.core.upload.UploadTask; +import com.arialyy.aria.core.upload.UploadTaskEntity; + +/** + * Created by Aria.Lao on 2017/2/27. + * 上传任务队列 + */ +public class UploadTaskQueue extends AbsTaskQueue { + private static final String TAG = "UploadTaskQueue"; + private static volatile UploadTaskQueue INSTANCE = null; + private static final Object LOCK = new Object(); + + public static UploadTaskQueue getInstance() { + if (INSTANCE == null) { + synchronized (LOCK) { + INSTANCE = new UploadTaskQueue(); + } + } + return INSTANCE; + } + + @Override public void startTask(UploadTask task) { + if (mExecutePool.putTask(task)) { + mCachePool.removeTask(task); + //task.getEntity().setFailNum(0); + task.start(); + } + } + + @Override public void stopTask(UploadTask task) { + if (!task.isRunning()) Log.w(TAG, "停止任务失败,【任务已经停止】"); + if (mExecutePool.removeTask(task)) { + task.stop(); + } else { + task.stop(); + Log.w(TAG, "停止任务失败,【任务已经停止】"); + } + } + + @Override public void cancelTask(UploadTask task) { + task.cancel(); + } + + @Override public void reTryStart(UploadTask task) { + if (task == null) { + Log.w(TAG, "重试下载失败,task 为null"); + return; + } + if (!task.isRunning()) { + task.start(); + } else { + Log.w(TAG, "任务没有完全停止,重试下载失败"); + } + } + + @Override public int size() { + return mExecutePool.size(); + } + + @Override public void setDownloadNum(int downloadNum) { + + } + + @Override public UploadTask createTask(String targetName, UploadTaskEntity entity) { + UploadTask task = null; + if (!TextUtils.isEmpty(targetName)) { + task = (UploadTask) TaskFactory.getInstance() + .createTask(targetName, entity, UploadSchedulers.getInstance()); + mCachePool.putTask(task); + } else { + Log.e(TAG, "target name 为 null是!!"); + } + return task; + } + + @Override public UploadTask getTask(UploadEntity entity) { + UploadTask task = mExecutePool.getTask(entity.getFilePath()); + if (task == null) { + task = mCachePool.getTask(entity.getFilePath()); + } + return task; + } + + @Override public void removeTask(UploadEntity entity) { + UploadTask task = mExecutePool.getTask(entity.getFilePath()); + if (task != null) { + Log.d(TAG, "从执行池删除任务,删除" + (mExecutePool.removeTask(task) ? "成功" : "失败")); + } + task = mCachePool.getTask(entity.getFilePath()); + if (task != null) { + Log.d(TAG, "从缓存池删除任务,删除" + (mCachePool.removeTask(task) ? "成功" : "失败")); + } + } + + @Override public UploadTask getNextTask() { + return mCachePool.pollTask(); + } +} diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/pool/CachePool.java b/Aria/src/main/java/com/arialyy/aria/core/queue/pool/CachePool.java index 86478b57..80ed971c 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/queue/pool/CachePool.java +++ b/Aria/src/main/java/com/arialyy/aria/core/queue/pool/CachePool.java @@ -19,7 +19,6 @@ package com.arialyy.aria.core.queue.pool; import android.text.TextUtils; import android.util.Log; import com.arialyy.aria.core.inf.ITask; -import com.arialyy.aria.core.queue.IPool; import com.arialyy.aria.util.CommonUtil; import java.util.HashMap; import java.util.Map; @@ -34,7 +33,6 @@ public class CachePool implements IPool { private static final String TAG = "CachePool"; private static final Object LOCK = new Object(); private static final int MAX_NUM = Integer.MAX_VALUE; //最大下载任务数 - private static volatile CachePool INSTANCE = null; private static final long TIME_OUT = 1000; private Map mCacheArray; private LinkedBlockingQueue mCacheQueue; @@ -44,15 +42,6 @@ public class CachePool implements IPool { mCacheArray = new HashMap<>(); } - //public static CachePool getInstance() { - // if (INSTANCE == null) { - // synchronized (LOCK) { - // INSTANCE = new CachePool(); - // } - // } - // return INSTANCE; - //} - @Override public boolean putTask(TASK task) { synchronized (LOCK) { if (task == null) { diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/pool/ExecutePool.java b/Aria/src/main/java/com/arialyy/aria/core/queue/pool/ExecutePool.java index 230b2f43..6b9b573d 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/queue/pool/ExecutePool.java +++ b/Aria/src/main/java/com/arialyy/aria/core/queue/pool/ExecutePool.java @@ -19,7 +19,6 @@ package com.arialyy.aria.core.queue.pool; import android.text.TextUtils; import android.util.Log; import com.arialyy.aria.core.inf.ITask; -import com.arialyy.aria.core.queue.IPool; import com.arialyy.aria.util.CommonUtil; import com.arialyy.aria.util.Configuration; import java.util.HashMap; @@ -35,7 +34,6 @@ public class ExecutePool implements IPool { private static final String TAG = "ExecutePool"; private static final Object LOCK = new Object(); private static final long TIME_OUT = 1000; - private static volatile ExecutePool INSTANCE = null; private ArrayBlockingQueue mExecuteQueue; private Map mExecuteArray; private int mSize; @@ -46,15 +44,6 @@ public class ExecutePool implements IPool { mExecuteArray = new HashMap<>(); } - //public static ExecutePool getInstance() { - // if (INSTANCE == null) { - // synchronized (LOCK) { - // INSTANCE = new ExecutePool(); - // } - // } - // return INSTANCE; - //} - @Override public boolean putTask(TASK task) { synchronized (LOCK) { if (task == null) { diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/IPool.java b/Aria/src/main/java/com/arialyy/aria/core/queue/pool/IPool.java similarity index 97% rename from Aria/src/main/java/com/arialyy/aria/core/queue/IPool.java rename to Aria/src/main/java/com/arialyy/aria/core/queue/pool/IPool.java index b65f22ca..31a19462 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/queue/IPool.java +++ b/Aria/src/main/java/com/arialyy/aria/core/queue/pool/IPool.java @@ -15,7 +15,7 @@ */ -package com.arialyy.aria.core.queue; +package com.arialyy.aria.core.queue.pool; import com.arialyy.aria.core.inf.ITask; diff --git a/Aria/src/main/java/com/arialyy/aria/core/scheduler/DownloadSchedulers.java b/Aria/src/main/java/com/arialyy/aria/core/scheduler/DownloadSchedulers.java index 2fc2d0c3..41c12be8 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/scheduler/DownloadSchedulers.java +++ b/Aria/src/main/java/com/arialyy/aria/core/scheduler/DownloadSchedulers.java @@ -19,8 +19,7 @@ package com.arialyy.aria.core.scheduler; import android.os.CountDownTimer; import android.os.Message; import android.util.Log; -import com.arialyy.aria.core.AriaManager; -import com.arialyy.aria.core.queue.ITaskQueue; +import com.arialyy.aria.core.queue.DownloadTaskQueue; import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.download.DownloadTask; import com.arialyy.aria.util.Configuration; @@ -33,39 +32,8 @@ import java.util.concurrent.ConcurrentHashMap; * Created by lyy on 2016/8/16. * 任务下载器,提供抽象的方法供具体的实现类操作 */ -public class DownloadSchedulers implements IDownloadSchedulers { - /** - * 任务预加载 - */ - public static final int PRE = 0; - /** - * 任务开始 - */ - public static final int START = 1; - /** - * 任务停止 - */ - public static final int STOP = 2; - /** - * 任务失败 - */ - public static final int FAIL = 3; - /** - * 任务取消 - */ - public static final int CANCEL = 4; - /** - * 任务完成 - */ - public static final int COMPLETE = 5; - /** - * 下载中 - */ - public static final int RUNNING = 6; - /** - * 恢复下载 - */ - public static final int RESUME = 7; +public class DownloadSchedulers implements ISchedulers { + private static final String TAG = "DownloadSchedulers"; private static final Object LOCK = new Object(); private static volatile DownloadSchedulers INSTANCE = null; @@ -73,37 +41,34 @@ public class DownloadSchedulers implements IDownloadSchedulers { /** * 下载器任务监听 */ - Map mSchedulerListeners = new ConcurrentHashMap<>(); - ITaskQueue mQueue; + private Map> mSchedulerListeners = + new ConcurrentHashMap<>(); + private DownloadTaskQueue mQueue; private DownloadSchedulers() { - mQueue = AriaManager.getInstance(AriaManager.APP).getTaskQueue(); + mQueue = DownloadTaskQueue.getInstance(); } public static DownloadSchedulers getInstance() { if (INSTANCE == null) { synchronized (LOCK) { - //INSTANCE = new DownloadSchedulers(queue); INSTANCE = new DownloadSchedulers(); } } - return INSTANCE; } - @Override - public void addSchedulerListener(String targetName, OnSchedulerListener schedulerListener) { + @Override public void addSchedulerListener(String targetName, + OnSchedulerListener schedulerListener) { mSchedulerListeners.put(targetName, schedulerListener); } - @Override - public void removeSchedulerListener(String targetName, OnSchedulerListener schedulerListener) { - //OnSchedulerListener listener = mSchedulerListeners.get(target.getClass().getName()); - //mSchedulerListeners.remove(listener); + @Override public void removeSchedulerListener(String targetName, + OnSchedulerListener schedulerListener) { //该内存溢出解决方案:http://stackoverflow.com/questions/14585829/how-safe-is-to-delete-already-removed-concurrenthashmap-element - for (Iterator> iter = + for (Iterator>> iter = mSchedulerListeners.entrySet().iterator(); iter.hasNext(); ) { - Map.Entry entry = iter.next(); + Map.Entry> entry = iter.next(); if (entry.getKey().equals(targetName)) iter.remove(); } } @@ -121,12 +86,12 @@ public class DownloadSchedulers implements IDownloadSchedulers { case CANCEL: mQueue.removeTask(entity); if (mQueue.size() < Configuration.getInstance().getDownloadNum()) { - startNextTask(entity); + startNextTask(); } break; case COMPLETE: mQueue.removeTask(entity); - startNextTask(entity); + startNextTask(); break; case FAIL: mQueue.removeTask(entity); @@ -153,7 +118,7 @@ public class DownloadSchedulers implements IDownloadSchedulers { } } - private void callback(int state, DownloadTask task, OnSchedulerListener listener) { + private void callback(int state, DownloadTask task, OnSchedulerListener listener) { if (listener != null) { if (task == null) { Log.e(TAG, "TASK 为null,回调失败"); @@ -193,7 +158,7 @@ public class DownloadSchedulers implements IDownloadSchedulers { * * @param entity 失败实体 */ - @Override public void handleFailTask(final DownloadEntity entity) { + private void handleFailTask(final DownloadEntity entity) { final Configuration config = Configuration.getInstance(); CountDownTimer timer = new CountDownTimer(config.getReTryInterval(), 1000) { @Override public void onTick(long millisUntilFinished) { @@ -210,7 +175,7 @@ public class DownloadSchedulers implements IDownloadSchedulers { e.printStackTrace(); } } else { - startNextTask(entity); + startNextTask(); } } }; @@ -219,10 +184,8 @@ public class DownloadSchedulers implements IDownloadSchedulers { /** * 启动下一个任务,条件:任务停止,取消下载,任务完成 - * - * @param entity 通过Handler传递的下载实体 */ - @Override public void startNextTask(DownloadEntity entity) { + private void startNextTask() { DownloadTask newTask = mQueue.getNextTask(); if (newTask == null) { Log.w(TAG, "没有下一任务"); diff --git a/Aria/src/main/java/com/arialyy/aria/core/scheduler/IDownloadSchedulers.java b/Aria/src/main/java/com/arialyy/aria/core/scheduler/ISchedulers.java similarity index 63% rename from Aria/src/main/java/com/arialyy/aria/core/scheduler/IDownloadSchedulers.java rename to Aria/src/main/java/com/arialyy/aria/core/scheduler/ISchedulers.java index 6100f461..f05b7a5b 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/scheduler/IDownloadSchedulers.java +++ b/Aria/src/main/java/com/arialyy/aria/core/scheduler/ISchedulers.java @@ -18,12 +18,45 @@ package com.arialyy.aria.core.scheduler; import android.os.Handler; import com.arialyy.aria.core.download.DownloadEntity; +import com.arialyy.aria.core.inf.ITask; /** * Created by “AriaLyy@outlook.com” on 2016/11/2. - * 下载调度器接口 + * 调度器功能接口 */ -public interface IDownloadSchedulers extends Handler.Callback { +public interface ISchedulers extends Handler.Callback { + /** + * 任务预加载 + */ + public static final int PRE = 0; + /** + * 任务开始 + */ + public static final int START = 1; + /** + * 任务停止 + */ + public static final int STOP = 2; + /** + * 任务失败 + */ + public static final int FAIL = 3; + /** + * 任务取消 + */ + public static final int CANCEL = 4; + /** + * 任务完成 + */ + public static final int COMPLETE = 5; + /** + * 任务处理中 + */ + public static final int RUNNING = 6; + /** + * 恢复任务 + */ + public static final int RESUME = 7; /** * 注册下载器监听,一个观察者只能注册一次监听 @@ -31,25 +64,12 @@ public interface IDownloadSchedulers extends Handler.Callback { * @param targetName 观察者,创建该监听器的对象类名 * @param schedulerListener {@link OnSchedulerListener} */ - public void addSchedulerListener(String targetName, OnSchedulerListener schedulerListener); + public void addSchedulerListener(String targetName, OnSchedulerListener schedulerListener); /** * @param targetName 观察者,创建该监听器的对象类名 * 取消注册监听器 */ - public void removeSchedulerListener(String targetName, OnSchedulerListener schedulerListener); + public void removeSchedulerListener(String targetName, OnSchedulerListener schedulerListener); - /** - * 处理下载任务下载失败的情形 - * - * @param entity 下载实体 - */ - public void handleFailTask(DownloadEntity entity); - - /** - * 启动下一个任务,条件:任务停止,取消下载,任务完成 - * - * @param entity 通过Handler传递的下载实体 - */ - public void startNextTask(DownloadEntity entity); } \ No newline at end of file diff --git a/Aria/src/main/java/com/arialyy/aria/core/scheduler/OnSchedulerListener.java b/Aria/src/main/java/com/arialyy/aria/core/scheduler/OnSchedulerListener.java index 457d5eaf..d27fcf67 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/scheduler/OnSchedulerListener.java +++ b/Aria/src/main/java/com/arialyy/aria/core/scheduler/OnSchedulerListener.java @@ -15,49 +15,49 @@ */ package com.arialyy.aria.core.scheduler; -import com.arialyy.aria.core.download.DownloadTask; +import com.arialyy.aria.core.inf.ITask; /** * Target处理任务监听 */ -public interface OnSchedulerListener { +public interface OnSchedulerListener { /** * 任务预加载 */ - public void onTaskPre(DownloadTask task); + public void onTaskPre(TASK task); /** * 任务恢复下载 */ - public void onTaskResume(DownloadTask task); + public void onTaskResume(TASK task); /** * 任务开始 */ - public void onTaskStart(DownloadTask task); + public void onTaskStart(TASK task); /** * 任务停止 */ - public void onTaskStop(DownloadTask task); + public void onTaskStop(TASK task); /** * 任务取消 */ - public void onTaskCancel(DownloadTask task); + public void onTaskCancel(TASK task); /** * 任务下载失败 */ - public void onTaskFail(DownloadTask task); + public void onTaskFail(TASK task); /** * 任务完成 */ - public void onTaskComplete(DownloadTask task); + public void onTaskComplete(TASK task); /** * 任务执行中 */ - public void onTaskRunning(DownloadTask task); + public void onTaskRunning(TASK task); } \ No newline at end of file diff --git a/Aria/src/main/java/com/arialyy/aria/core/scheduler/UploadSchedulers.java b/Aria/src/main/java/com/arialyy/aria/core/scheduler/UploadSchedulers.java new file mode 100644 index 00000000..86930b68 --- /dev/null +++ b/Aria/src/main/java/com/arialyy/aria/core/scheduler/UploadSchedulers.java @@ -0,0 +1,187 @@ +/* + * 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.scheduler; + +import android.os.CountDownTimer; +import android.os.Message; +import android.util.Log; +import com.arialyy.aria.core.download.DownloadEntity; +import com.arialyy.aria.core.download.DownloadTask; +import com.arialyy.aria.core.inf.IEntity; +import com.arialyy.aria.core.queue.UploadTaskQueue; +import com.arialyy.aria.core.upload.UploadEntity; +import com.arialyy.aria.core.upload.UploadTask; +import com.arialyy.aria.util.Configuration; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Created by Aria.Lao on 2017/2/27. + * 上传任务调度器 + */ +public class UploadSchedulers implements ISchedulers { + private static final String TAG = "UploadSchedulers"; + private static final Object LOCK = new Object(); + private static volatile UploadSchedulers INSTANCE = null; + private Map> mSchedulerListeners = + new ConcurrentHashMap<>(); + private UploadTaskQueue mQueue; + + private UploadSchedulers() { + mQueue = UploadTaskQueue.getInstance(); + } + + public static UploadSchedulers getInstance() { + if (INSTANCE == null) { + synchronized (LOCK) { + INSTANCE = new UploadSchedulers(); + } + } + + return INSTANCE; + } + + @Override public void addSchedulerListener(String targetName, + OnSchedulerListener schedulerListener) { + mSchedulerListeners.put(targetName, schedulerListener); + } + + @Override public void removeSchedulerListener(String targetName, + OnSchedulerListener schedulerListener) { + for (Iterator>> iter = + mSchedulerListeners.entrySet().iterator(); iter.hasNext(); ) { + Map.Entry> entry = iter.next(); + if (entry.getKey().equals(targetName)) iter.remove(); + } + } + + private void handleFailTask(final UploadEntity entity) { + final Configuration config = Configuration.getInstance(); + CountDownTimer timer = new CountDownTimer(config.getReTryInterval(), 1000) { + @Override public void onTick(long millisUntilFinished) { + + } + + @Override public void onFinish() { + if (entity.getFailNum() <= config.getReTryNum()) { + UploadTask task = mQueue.getTask(entity); + mQueue.reTryStart(task); + try { + Thread.sleep(config.getReTryInterval()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } else { + startNextTask(); + } + } + }; + timer.start(); + } + + private void startNextTask() { + UploadTask newTask = mQueue.getNextTask(); + if (newTask == null) { + Log.w(TAG, "没有下一任务"); + return; + } + if (newTask.getUploadEntity().getState() == IEntity.STATE_WAIT) { + mQueue.startTask(newTask); + } + } + + /** + * 回调 + * + * @param state 状态 + */ + private void callback(int state, UploadTask task) { + if (mSchedulerListeners.size() > 0) { + //if (!TextUtils.isEmpty(task.getTargetName())) { + // callback(state, task, mSchedulerListeners.get(task.getTargetName())); + //} + Set keys = mSchedulerListeners.keySet(); + for (String key : keys) { + callback(state, task, mSchedulerListeners.get(key)); + } + } + } + + private void callback(int state, UploadTask task, OnSchedulerListener listener) { + if (listener != null) { + if (task == null) { + Log.e(TAG, "TASK 为null,回调失败"); + return; + } + switch (state) { + case RUNNING: + listener.onTaskRunning(task); + break; + case START: + listener.onTaskStart(task); + break; + case STOP: + listener.onTaskStop(task); + break; + case RESUME: + listener.onTaskResume(task); + break; + case PRE: + listener.onTaskPre(task); + break; + case CANCEL: + listener.onTaskCancel(task); + break; + case COMPLETE: + listener.onTaskComplete(task); + break; + case FAIL: + listener.onTaskFail(task); + break; + } + } + } + + @Override public boolean handleMessage(Message msg) { + UploadTask task = (UploadTask) msg.obj; + if (task == null) { + Log.e(TAG, "请传入上传任务"); + return true; + } + callback(msg.what, task); + UploadEntity entity = task.getUploadEntity(); + switch (msg.what) { + case STOP: + case CANCEL: + mQueue.removeTask(entity); + if (mQueue.size() < Configuration.getInstance().getDownloadNum()) { + startNextTask(); + } + break; + case COMPLETE: + mQueue.removeTask(entity); + startNextTask(); + break; + case FAIL: + mQueue.removeTask(entity); + handleFailTask(entity); + break; + } + return true; + } +} diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadEntity.java b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadEntity.java index 72f5dc98..5992a657 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadEntity.java +++ b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadEntity.java @@ -1,18 +1,73 @@ package com.arialyy.aria.core.upload; -import com.arialyy.aria.core.download.DownloadEntity; +import android.os.Parcel; +import android.os.Parcelable; import com.arialyy.aria.core.inf.IEntity; import com.arialyy.aria.orm.DbEntity; +import com.arialyy.aria.orm.Ignore; /** * Created by Aria.Lao on 2017/2/9. * 上传文件实体 */ -public class UploadEntity implements IEntity{ +public class UploadEntity extends DbEntity implements IEntity, Parcelable { private String filePath; //文件路径 private String fileName; //文件名 private long fileSize; //文件大小 + private int state = STATE_WAIT; + private long currentProgress = 0; + private boolean isComplete = false; + @Ignore private long speed = 0; //下载速度 + @Ignore private int failNum = 0; + + public boolean isComplete() { + return isComplete; + } + + public void setComplete(boolean complete) { + isComplete = complete; + } + + public long getCurrentProgress() { + return currentProgress; + } + + public void setCurrentProgress(long currentProgress) { + this.currentProgress = currentProgress; + } + + public long getFileSize() { + return fileSize; + } + + public void setFileSize(long fileSize) { + this.fileSize = fileSize; + } + + public long getSpeed() { + return speed; + } + + public void setSpeed(long speed) { + this.speed = speed; + } + + public int getFailNum() { + return failNum; + } + + public void setFailNum(int failNum) { + this.failNum = failNum; + } + + public int getState() { + return state; + } + + public void setState(int state) { + this.state = state; + } public String getFilePath() { return filePath; @@ -30,4 +85,43 @@ public class UploadEntity implements IEntity{ this.fileName = fileName; } + public UploadEntity() { + } + + @Override public int describeContents() { + return 0; + } + + @Override public void writeToParcel(Parcel dest, int flags) { + dest.writeString(this.filePath); + dest.writeString(this.fileName); + dest.writeLong(this.fileSize); + dest.writeInt(this.state); + dest.writeLong(this.currentProgress); + dest.writeByte(this.isComplete ? (byte) 1 : (byte) 0); + dest.writeLong(this.speed); + dest.writeInt(this.failNum); + } + + protected UploadEntity(Parcel in) { + this.filePath = in.readString(); + this.fileName = in.readString(); + this.fileSize = in.readLong(); + this.state = in.readInt(); + this.currentProgress = in.readLong(); + this.isComplete = in.readByte() != 0; + this.speed = in.readLong(); + this.failNum = in.readInt(); + } + + @Ignore + public static final Creator CREATOR = new Creator() { + @Override public UploadEntity createFromParcel(Parcel source) { + return new UploadEntity(source); + } + + @Override public UploadEntity[] newArray(int size) { + return new UploadEntity[size]; + } + }; } diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadTask.java b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadTask.java index a13153b8..6ed54b3c 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadTask.java +++ b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadTask.java @@ -1,22 +1,43 @@ package com.arialyy.aria.core.upload; +import android.content.Intent; import android.os.Handler; +import android.util.Log; +import com.arialyy.aria.core.Aria; +import com.arialyy.aria.core.AriaManager; +import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.inf.IEntity; import com.arialyy.aria.core.inf.ITask; +import com.arialyy.aria.core.scheduler.DownloadSchedulers; +import com.arialyy.aria.core.scheduler.ISchedulers; +import com.arialyy.aria.util.CommonUtil; +import com.arialyy.aria.util.Configuration; +import java.lang.ref.WeakReference; /** * Created by Aria.Lao on 2017/2/23. * 上传任务 */ public class UploadTask implements ITask { + private static final String TAG = "UploadTask"; private Handler mOutHandler; private UploadTaskEntity mTaskEntity; private UploadEntity mUploadEntity; + private String mTargetName; + + private UploadUtil mUtil; + private UListener mListener; UploadTask(UploadTaskEntity taskEntity, Handler outHandler) { mTaskEntity = taskEntity; mOutHandler = outHandler; mUploadEntity = mTaskEntity.uploadEntity; + mListener = new UListener(mOutHandler, this); + mUtil = new UploadUtil(mTaskEntity, mListener); + } + + void setTargetName(String targetName) { + mTargetName = targetName; } @Override public String getKey() { @@ -27,12 +48,23 @@ public class UploadTask implements ITask { return false; } + public UploadEntity getUploadEntity() { + return mUploadEntity; + } + @Override public IEntity getEntity() { return mUploadEntity; } @Override public void start() { - + if (mUtil.isRunning()) { + Log.d(TAG, "任务正在下载"); + } else { + if (mListener == null) { + mListener = new UploadTask.UListener(mOutHandler, this); + } + mUtil.start(); + } } @Override public void stop() { @@ -40,75 +72,175 @@ public class UploadTask implements ITask { } @Override public void cancel() { + if (mUtil.isRunning()) { + mUtil.cancel(); + } else { + // 如果任务不是下载状态 + mUtil.cancel(); + mUploadEntity.deleteData(); + if (mOutHandler != null) { + mOutHandler.obtainMessage(DownloadSchedulers.CANCEL, this).sendToTarget(); + } + //发送取消下载的广播 + Intent intent = CommonUtil.createIntent(AriaManager.APP.getPackageName(), Aria.ACTION_CANCEL); + intent.putExtra(Aria.ENTITY, mUploadEntity); + AriaManager.APP.sendBroadcast(intent); + } + } + public String getTargetName() { + return mTargetName; } @Override public long getSpeed() { - return 0; + return mUploadEntity.getSpeed(); } @Override public long getFileSize() { - return 0; + return mUploadEntity.getFileSize(); } @Override public long getCurrentProgress() { - return 0; + return mUploadEntity.getCurrentProgress(); } - private static class UListener extends UploadListener{ - @Override public void onPre() { + private static class UListener extends UploadListener { + WeakReference outHandler; + WeakReference task; + long lastLen = 0; //上一次发送长度 + long lastTime = 0; + long INTERVAL_TIME = 1000; //1m更新周期 + boolean isFirst = true; + UploadEntity entity; + Intent sendIntent; + UListener(Handler outHandle, UploadTask task) { + this.outHandler = new WeakReference<>(outHandle); + this.task = new WeakReference<>(task); + entity = this.task.get().getUploadEntity(); + sendIntent = CommonUtil.createIntent(AriaManager.APP.getPackageName(), Aria.ACTION_RUNNING); + sendIntent.putExtra(Aria.ENTITY, entity); + } + + @Override public void onPre() { + entity.setState(IEntity.STATE_PRE); + sendIntent(Aria.ACTION_PRE, -1); + sendInState2Target(ISchedulers.PRE); } @Override public void onStart(long fileSize) { - + entity.setFileSize(fileSize); + entity.setState(IEntity.STATE_RUNNING); + sendIntent(Aria.ACTION_PRE, -1); + sendInState2Target(ISchedulers.START); } @Override public void onResume(long resumeLocation) { - + entity.setState(DownloadEntity.STATE_RUNNING); + sendInState2Target(DownloadSchedulers.RESUME); + sendIntent(Aria.ACTION_RESUME, resumeLocation); } @Override public void onStop(long stopLocation) { - + entity.setState(DownloadEntity.STATE_STOP); + entity.setSpeed(0); + sendInState2Target(DownloadSchedulers.STOP); + sendIntent(Aria.ACTION_STOP, stopLocation); } @Override public void onProgress(long currentLocation) { - + if (System.currentTimeMillis() - lastTime > INTERVAL_TIME) { + long speed = currentLocation - lastLen; + sendIntent.putExtra(Aria.CURRENT_LOCATION, currentLocation); + sendIntent.putExtra(Aria.CURRENT_SPEED, speed); + lastTime = System.currentTimeMillis(); + if (isFirst) { + entity.setSpeed(0); + isFirst = false; + } else { + entity.setSpeed(speed); + } + entity.setCurrentProgress(currentLocation); + lastLen = currentLocation; + sendInState2Target(DownloadSchedulers.RUNNING); + AriaManager.APP.sendBroadcast(sendIntent); + } } @Override public void onCancel() { - + entity.setState(DownloadEntity.STATE_CANCEL); + sendInState2Target(DownloadSchedulers.CANCEL); + sendIntent(Aria.ACTION_CANCEL, -1); + entity.deleteData(); } @Override public void onComplete() { - + entity.setState(DownloadEntity.STATE_COMPLETE); + entity.setComplete(true); + entity.setSpeed(0); + sendInState2Target(DownloadSchedulers.COMPLETE); + sendIntent(Aria.ACTION_COMPLETE, entity.getFileSize()); } @Override public void onFail() { + entity.setFailNum(entity.getFailNum() + 1); + entity.setState(DownloadEntity.STATE_FAIL); + entity.setSpeed(0); + sendInState2Target(DownloadSchedulers.FAIL); + sendIntent(Aria.ACTION_FAIL, -1); + } + /** + * 将任务状态发送给下载器 + * + * @param state {@link DownloadSchedulers#START} + */ + private void sendInState2Target(int state) { + if (outHandler.get() != null) { + outHandler.get().obtainMessage(state, task).sendToTarget(); + } + } + + private void sendIntent(String action, long location) { + entity.setComplete(action.equals(Aria.ACTION_COMPLETE)); + entity.setCurrentProgress(location); + entity.update(); + Intent intent = CommonUtil.createIntent(AriaManager.APP.getPackageName(), action); + intent.putExtra(Aria.ENTITY, entity); + if (location != -1) { + intent.putExtra(Aria.CURRENT_LOCATION, location); + } + if (Configuration.isOpenBreadCast) { + AriaManager.APP.sendBroadcast(intent); + } } } - static class Builder { + public static class Builder { private Handler mOutHandler; private UploadTaskEntity mTaskEntity; + private String mTargetName; - public void setOutHandler(Handler outHandler){ - mOutHandler = outHandler; + public void setOutHandler(ISchedulers outHandler) { + mOutHandler = new Handler(outHandler); } - public void setUploadTaskEntity(UploadTaskEntity taskEntity){ + public void setUploadTaskEntity(UploadTaskEntity taskEntity) { mTaskEntity = taskEntity; } - public Builder(){ + public void setTargetName(String targetName) { + mTargetName = targetName; + } + + public Builder() { } - public UploadTask build(){ + public UploadTask build() { UploadTask task = new UploadTask(mTaskEntity, mOutHandler); + task.setTargetName(mTargetName); return task; } - } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadTaskQueue.java b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadTaskQueue.java deleted file mode 100644 index ec84c08b..00000000 --- a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadTaskQueue.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.arialyy.aria.core.upload; - -import com.arialyy.aria.core.queue.ITaskQueue; - -/** - * Created by Aria.Lao on 2017/2/23. - */ - -public class UploadTaskQueue implements ITaskQueue{ - @Override public void startTask(UploadTask task) { - - } - - @Override public void stopTask(UploadTask task) { - - } - - @Override public void cancelTask(UploadTask task) { - - } - - @Override public void reTryStart(UploadTask task) { - - } - - @Override public int size() { - return 0; - } - - @Override public void setDownloadNum(int downloadNum) { - - } - - @Override public UploadTask createTask(String targetName, UploadTaskEntity entity) { - return null; - } - - @Override public UploadTask getTask(UploadEntity entity) { - return null; - } - - @Override public void removeTask(UploadEntity entity) { - - } - - @Override public UploadTask getNextTask() { - return null; - } -} diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadUtil.java b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadUtil.java index 3e1e538c..12e5a702 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadUtil.java +++ b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadUtil.java @@ -32,6 +32,8 @@ public class UploadUtil implements Runnable { private OutputStream mOutputStream; private HttpURLConnection mHttpConn; private long mCurrentLocation = 0; + private boolean isCancel = false; + private boolean isRunning = false; public UploadUtil(UploadTaskEntity taskEntity, IUploadListener listener) { mTaskEntity = taskEntity; @@ -44,14 +46,21 @@ public class UploadUtil implements Runnable { } public void start() { + isCancel = false; + isRunning = false; new Thread(this).start(); } + public void cancel(){ + isCancel = true; + isRunning = false; + } + @Override public void run() { File uploadFile = new File(mUploadEntity.getFilePath()); if (!uploadFile.exists()) { Log.e(TAG, "【" + mUploadEntity.getFilePath() + "】,文件不存在。"); - mListener.onFail(); + fail(); return; } @@ -66,7 +75,7 @@ public class UploadUtil implements Runnable { mHttpConn.setDoInput(true); mHttpConn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY); mHttpConn.setRequestProperty("User-Agent", "CodeJava Agent"); - mHttpConn.setRequestProperty("Range", "bytes=" + 0 + "-" + "100"); + //mHttpConn.setRequestProperty("Range", "bytes=" + 0 + "-" + "100"); //内部缓冲区---分段上传防止oom mHttpConn.setChunkedStreamingMode(1024); @@ -89,11 +98,23 @@ public class UploadUtil implements Runnable { Log.d(TAG, finish() + ""); } catch (MalformedURLException e) { e.printStackTrace(); + fail(); } catch (IOException e) { e.printStackTrace(); + fail(); } } + public boolean isRunning() { + return isRunning; + } + + private void fail() { + mWriter.flush(); + mWriter.close(); + mListener.onFail(); + } + /** * 添加文件上传表单字段 */ @@ -139,13 +160,23 @@ public class UploadUtil implements Runnable { while ((bytesRead = inputStream.read(buffer)) != -1) { mCurrentLocation += bytesRead; mOutputStream.write(buffer, 0, bytesRead); + if (isCancel) { + break; + } + isRunning = true; mListener.onProgress(mCurrentLocation); } + mOutputStream.flush(); inputStream.close(); - mListener.onComplete(); mWriter.append(LINE_END); mWriter.flush(); + isRunning = false; + if (isCancel) { + mListener.onCancel(); + return; + } + mListener.onComplete(); } /** @@ -173,6 +204,9 @@ public class UploadUtil implements Runnable { throw new IOException("Server returned non-OK status: " + status); } + mWriter.flush(); + mWriter.close(); + return response.toString(); } } diff --git a/app/src/main/java/com/arialyy/simple/dialog_task/DownloadDialog.java b/app/src/main/java/com/arialyy/simple/dialog_task/DownloadDialog.java index f0b30114..f1092a96 100644 --- a/app/src/main/java/com/arialyy/simple/dialog_task/DownloadDialog.java +++ b/app/src/main/java/com/arialyy/simple/dialog_task/DownloadDialog.java @@ -84,7 +84,7 @@ public class DownloadDialog extends AbsDialog { mStop.setEnabled(!startEnable); } - private class MyDialogDownloadCallback extends Aria.SimpleSchedulerListener { + private class MyDialogDownloadCallback extends Aria.DownloadSchedulerListener { @Override public void onTaskPre(DownloadTask task) { super.onTaskPre(task); diff --git a/app/src/main/java/com/arialyy/simple/fragment_task/DownloadFragment.java b/app/src/main/java/com/arialyy/simple/fragment_task/DownloadFragment.java index dc2cc461..edd7155a 100644 --- a/app/src/main/java/com/arialyy/simple/fragment_task/DownloadFragment.java +++ b/app/src/main/java/com/arialyy/simple/fragment_task/DownloadFragment.java @@ -88,7 +88,7 @@ public class DownloadFragment extends AbsFragment { mStop.setEnabled(!startEnable); } - private class MyDialogDownloadCallback extends Aria.SimpleSchedulerListener { + private class MyDialogDownloadCallback extends Aria.DownloadSchedulerListener { @Override public void onTaskPre(DownloadTask task) { super.onTaskPre(task); diff --git a/app/src/main/java/com/arialyy/simple/multi_task/DownloadActivity.java b/app/src/main/java/com/arialyy/simple/multi_task/DownloadActivity.java index 705d34de..a8ccc441 100644 --- a/app/src/main/java/com/arialyy/simple/multi_task/DownloadActivity.java +++ b/app/src/main/java/com/arialyy/simple/multi_task/DownloadActivity.java @@ -39,7 +39,7 @@ public class DownloadActivity extends BaseActivity { Aria.download(this).addSchedulerListener(new MySchedulerListener()); } - private class MySchedulerListener extends Aria.SimpleSchedulerListener { + private class MySchedulerListener extends Aria.DownloadSchedulerListener { @Override public void onTaskPre(DownloadTask task) { super.onTaskPre(task); L.d(TAG, "download pre"); diff --git a/app/src/main/java/com/arialyy/simple/multi_task/MultiTaskActivity.java b/app/src/main/java/com/arialyy/simple/multi_task/MultiTaskActivity.java index 015f0355..e8cb4af5 100644 --- a/app/src/main/java/com/arialyy/simple/multi_task/MultiTaskActivity.java +++ b/app/src/main/java/com/arialyy/simple/multi_task/MultiTaskActivity.java @@ -87,7 +87,7 @@ public class MultiTaskActivity extends BaseActivity { } } - private class DownloadListener extends Aria.SimpleSchedulerListener { + private class DownloadListener extends Aria.DownloadSchedulerListener { @Override public void onTaskStart(DownloadTask task) { super.onTaskStart(task); diff --git a/app/src/main/java/com/arialyy/simple/notification/SimpleNotification.java b/app/src/main/java/com/arialyy/simple/notification/SimpleNotification.java index 2e0ea621..e16d1d87 100644 --- a/app/src/main/java/com/arialyy/simple/notification/SimpleNotification.java +++ b/app/src/main/java/com/arialyy/simple/notification/SimpleNotification.java @@ -50,7 +50,7 @@ public class SimpleNotification { Aria.download(mContext).load(DOWNLOAD_URL).stop(); } - private static class DownloadCallback extends Aria.SimpleSchedulerListener { + private static class DownloadCallback extends Aria.DownloadSchedulerListener { NotificationCompat.Builder mBuilder; NotificationManager mManager; diff --git a/app/src/main/java/com/arialyy/simple/pop_task/DownloadPopupWindow.java b/app/src/main/java/com/arialyy/simple/pop_task/DownloadPopupWindow.java index badb471d..176ba3e0 100644 --- a/app/src/main/java/com/arialyy/simple/pop_task/DownloadPopupWindow.java +++ b/app/src/main/java/com/arialyy/simple/pop_task/DownloadPopupWindow.java @@ -86,7 +86,7 @@ public class DownloadPopupWindow extends AbsPopupWindow { mStop.setEnabled(!startEnable); } - private class MyDialogDownloadCallback extends Aria.SimpleSchedulerListener { + private class MyDialogDownloadCallback extends Aria.DownloadSchedulerListener { @Override public void onTaskPre(DownloadTask task) { super.onTaskPre(task); diff --git a/app/src/main/java/com/arialyy/simple/single_task/SingleTaskActivity.java b/app/src/main/java/com/arialyy/simple/single_task/SingleTaskActivity.java index b889b3ce..be786867 100644 --- a/app/src/main/java/com/arialyy/simple/single_task/SingleTaskActivity.java +++ b/app/src/main/java/com/arialyy/simple/single_task/SingleTaskActivity.java @@ -207,7 +207,7 @@ public class SingleTaskActivity extends BaseActivity { Aria.download(this).load(DOWNLOAD_URL).cancel(); } - private class MySchedulerListener extends Aria.SimpleSchedulerListener { + private class MySchedulerListener extends Aria.DownloadSchedulerListener { @Override public void onTaskStart(DownloadTask task) { mUpdateHandler.obtainMessage(DOWNLOAD_PRE, task.getDownloadEntity().getFileSize()) .sendToTarget();