diff --git a/.idea/modules.xml b/.idea/modules.xml index 5f6de159..9f4bd159 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -2,8 +2,8 @@ - + 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 8857685f..a897e990 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/Aria.java +++ b/Aria/src/main/java/com/arialyy/aria/core/Aria.java @@ -27,7 +27,9 @@ import android.content.Context; import android.os.Build; import android.widget.PopupWindow; import com.arialyy.aria.core.download.DownloadReceiver; -import com.arialyy.aria.core.scheduler.OnSchedulerListener; +import com.arialyy.aria.core.scheduler.DownloadSchedulers; +import com.arialyy.aria.core.scheduler.IDownloadSchedulerListener; +import com.arialyy.aria.core.scheduler.ISchedulerListener; import com.arialyy.aria.core.download.DownloadTask; import com.arialyy.aria.core.upload.UploadReceiver; import com.arialyy.aria.core.upload.UploadTask; @@ -56,6 +58,10 @@ import com.arialyy.aria.core.upload.UploadTask; * */ @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) public class Aria { + /** + * 不支持断点 + */ + public static final String ACTION_SUPPORT_BREAK_POINT = "ACTION_SUPPORT_BREAK_POINT"; /** * 预处理完成 */ @@ -163,7 +169,7 @@ import com.arialyy.aria.core.upload.UploadTask; /** * 上传任务状态监听 */ - public static class UploadSchedulerListener implements OnSchedulerListener { + public static class UploadSchedulerListener implements ISchedulerListener { @Override public void onTaskPre(UploadTask task) { @@ -201,7 +207,8 @@ import com.arialyy.aria.core.upload.UploadTask; /** * 下载任务状态监听 */ - public static class DownloadSchedulerListener implements OnSchedulerListener { + public static class DownloadSchedulerListener implements + IDownloadSchedulerListener { @Override public void onTaskPre(DownloadTask task) { @@ -234,5 +241,9 @@ import com.arialyy.aria.core.upload.UploadTask; @Override public void onTaskRunning(DownloadTask task) { } + + @Override public void onNoSupportBreakPoint(DownloadTask task) { + + } } } 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 7643e2b2..06c12003 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 @@ -32,9 +32,9 @@ class AddCmd extends AbsCmd { @Override public void executeCmd() { ITask task = mQueue.getTask(mEntity.getEntity()); - if (task == null){ + if (task == null) { mQueue.createTask(mTargetName, mEntity); - }else { + } else { Log.w(TAG, "添加命令执行失败,【该任务已经存在】"); } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/StartCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/StartCmd.java index 30d03d91..bec05307 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/command/StartCmd.java +++ b/Aria/src/main/java/com/arialyy/aria/core/command/StartCmd.java @@ -31,7 +31,6 @@ class StartCmd extends AbsCmd { } @Override public void executeCmd() { - Log.d(TAG, "startCmd"); ITask task = mQueue.getTask(mEntity.getEntity()); if (task == null) { task = mQueue.createTask(mTargetName, mEntity); diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadEntity.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadEntity.java index 479d2652..3ab34a32 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadEntity.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadEntity.java @@ -14,7 +14,6 @@ * limitations under the License. */ - package com.arialyy.aria.core.download; import android.os.Parcel; @@ -30,7 +29,7 @@ import com.arialyy.aria.orm.DbEntity; * !!! 注意:CREATOR要进行@Ignore注解 * !!!并且需要Parcelable时需要手动填写rowID; */ -public class DownloadEntity extends DbEntity implements Parcelable, IEntity{ +public class DownloadEntity extends DbEntity implements Parcelable, IEntity { @Ignore public static final Creator CREATOR = new Creator() { @Override public DownloadEntity createFromParcel(Parcel source) { return new DownloadEntity(source); @@ -40,16 +39,16 @@ public class DownloadEntity extends DbEntity implements Parcelable, IEntity{ return new DownloadEntity[size]; } }; - @Ignore private long speed = 0; //下载速度 - @Ignore private int failNum = 0; - private String downloadUrl = ""; //下载路径 - private String downloadPath = ""; //保存路径 - private String fileName = ""; //文件名 - private String str = ""; //其它字段 - private long fileSize = 1; - private int state = STATE_WAIT; - private boolean isDownloadComplete = false; //是否下载完成 - private long currentProgress = 0; //当前下载进度 + @Ignore private long speed = 0; //下载速度 + @Ignore private int failNum = 0; + private String downloadUrl = ""; //下载路径 + private String downloadPath = ""; //保存路径 + private String fileName = ""; //文件名 + private String str = ""; //其它字段 + private long fileSize = 1; + private int state = STATE_WAIT; + private boolean isDownloadComplete = false; //是否下载完成 + private long currentProgress = 0; //当前下载进度 private long completeTime; //完成时间 public DownloadEntity() { @@ -129,8 +128,7 @@ public class DownloadEntity extends DbEntity implements Parcelable, IEntity{ this.fileSize = fileSize; } - @Override - public int getState() { + @Override public int getState() { return state; } @@ -167,16 +165,26 @@ public class DownloadEntity extends DbEntity implements Parcelable, IEntity{ } @Override public String toString() { - return "DownloadEntity{" + - "downloadUrl='" + downloadUrl + '\'' + - ", downloadPath='" + downloadPath + '\'' + - ", completeTime=" + completeTime + - ", fileSize=" + fileSize + - ", state=" + state + - ", isDownloadComplete=" + isDownloadComplete + - ", currentProgress=" + currentProgress + - ", failNum=" + failNum + - '}'; + return "DownloadEntity{" + + "downloadUrl='" + + downloadUrl + + '\'' + + ", downloadPath='" + + downloadPath + + '\'' + + ", completeTime=" + + completeTime + + ", fileSize=" + + fileSize + + ", state=" + + state + + ", isDownloadComplete=" + + isDownloadComplete + + ", currentProgress=" + + currentProgress + + ", failNum=" + + failNum + + '}'; } @Override public int describeContents() { diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadListener.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadListener.java index 92d32b75..b74f48a7 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadListener.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadListener.java @@ -14,7 +14,6 @@ * limitations under the License. */ - package com.arialyy.aria.core.download; class DownloadListener implements IDownloadListener { diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java index 508949d1..d52a18af 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java @@ -21,7 +21,7 @@ import com.arialyy.aria.core.inf.IReceiver; import com.arialyy.aria.core.command.CmdFactory; import com.arialyy.aria.core.command.AbsCmd; import com.arialyy.aria.core.scheduler.DownloadSchedulers; -import com.arialyy.aria.core.scheduler.OnSchedulerListener; +import com.arialyy.aria.core.scheduler.ISchedulerListener; import com.arialyy.aria.orm.DbEntity; import com.arialyy.aria.util.CheckUtil; import com.arialyy.aria.util.CommonUtil; @@ -36,7 +36,7 @@ import java.util.Set; public class DownloadReceiver implements IReceiver { private static final String TAG = "DownloadReceiver"; public String targetName; - public OnSchedulerListener listener; + public ISchedulerListener listener; /** * {@link #load(String)},请使用该方法 @@ -62,7 +62,7 @@ public class DownloadReceiver implements IReceiver { /** * 添加调度器回调 */ - public DownloadReceiver addSchedulerListener(OnSchedulerListener listener) { + public DownloadReceiver addSchedulerListener(ISchedulerListener listener) { this.listener = listener; DownloadSchedulers.getInstance().addSchedulerListener(targetName, listener); return this; @@ -110,8 +110,8 @@ public class DownloadReceiver implements IReceiver { List stopCmds = new ArrayList<>(); for (DownloadEntity entity : allEntity) { if (entity.getState() == DownloadEntity.STATE_RUNNING) { - stopCmds.add(CommonUtil.createCmd(targetName, new DownloadTaskEntity(entity), - CmdFactory.TASK_STOP)); + stopCmds.add( + CommonUtil.createCmd(targetName, new DownloadTaskEntity(entity), CmdFactory.TASK_STOP)); } } ariaManager.setCmds(stopCmds).exe(); @@ -125,8 +125,8 @@ public class DownloadReceiver implements IReceiver { List allEntity = DbEntity.findAllData(DownloadEntity.class); List cancelCmds = new ArrayList<>(); for (DownloadEntity entity : allEntity) { - cancelCmds.add(CommonUtil.createCmd(targetName, new DownloadTaskEntity(entity), - CmdFactory.TASK_CANCEL)); + cancelCmds.add( + CommonUtil.createCmd(targetName, new DownloadTaskEntity(entity), CmdFactory.TASK_CANCEL)); } ariaManager.setCmds(cancelCmds).exe(); Set keys = ariaManager.getReceiver().keySet(); diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadStateConstance.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadStateConstance.java index e8b69bad..934ff001 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadStateConstance.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadStateConstance.java @@ -20,17 +20,17 @@ package com.arialyy.aria.core.download; * 下载状态常量 */ final class DownloadStateConstance { - int CANCEL_NUM = 0; - int STOP_NUM = 0; - int FAIL_NUM = 0; - int CONNECT_TIME_OUT = 5000 * 4; //连接超时时间 - int READ_TIME_OUT = 1000 * 20; //流读取的超时时间 - int COMPLETE_THREAD_NUM = 0; - int THREAD_NUM = 3; - long CURRENT_LOCATION = 0; - boolean isDownloading = false; - boolean isCancel = false; - boolean isStop = false; + int CANCEL_NUM = 0; + int STOP_NUM = 0; + int FAIL_NUM = 0; + int CONNECT_TIME_OUT = 5000 * 4; //连接超时时间 + int READ_TIME_OUT = 1000 * 20; //流读取的超时时间 + int COMPLETE_THREAD_NUM = 0; + int THREAD_NUM = 3; + long CURRENT_LOCATION = 0; + boolean isDownloading = false; + boolean isCancel = false; + boolean isStop = false; DownloadStateConstance() { } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTarget.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTarget.java index eedd7cd4..42e28a98 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTarget.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTarget.java @@ -91,8 +91,7 @@ public class DownloadTarget extends AbsTarget mTask = new SparseArray<>(); private DownloadStateConstance mConstance; @@ -303,7 +303,7 @@ final class DownloadUtil implements IDownloadUtil, Runnable { /** * 处理不支持断点的下载 */ - private void handleNoSupportBreakpointDownload(HttpURLConnection conn){ + private void handleNoSupportBreakpointDownload(HttpURLConnection conn) { ConfigEntity entity = new ConfigEntity(); long len = conn.getContentLength(); entity.FILE_SIZE = len; @@ -315,7 +315,10 @@ final class DownloadUtil implements IDownloadUtil, Runnable { entity.CONFIG_FILE_PATH = mConfigFile.getPath(); entity.isSupportBreakpoint = isSupportBreakpoint; entity.DOWNLOAD_TASK_ENTITY = mDownloadTaskEntity; + THREAD_NUM = 1; + mConstance.THREAD_NUM = THREAD_NUM; SingleThreadTask task = new SingleThreadTask(mConstance, mListener, entity); + mTask.put(0, task); mFixedThreadPool.execute(task); mListener.onPostPre(len); mListener.onStart(0); @@ -415,13 +418,13 @@ final class DownloadUtil implements IDownloadUtil, Runnable { */ final static class ConfigEntity { //文件大小 - int THREAD_ID; - long FILE_SIZE; - long START_LOCATION; - long END_LOCATION; - File TEMP_FILE; - String DOWNLOAD_URL; - String CONFIG_FILE_PATH; + int THREAD_ID; + long FILE_SIZE; + long START_LOCATION; + long END_LOCATION; + File TEMP_FILE; + String DOWNLOAD_URL; + String CONFIG_FILE_PATH; DownloadTaskEntity DOWNLOAD_TASK_ENTITY; boolean isSupportBreakpoint = true; } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/IDownloadUtil.java b/Aria/src/main/java/com/arialyy/aria/core/download/IDownloadUtil.java index 17396e89..45b4cc5e 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/IDownloadUtil.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/IDownloadUtil.java @@ -14,7 +14,6 @@ * limitations under the License. */ - package com.arialyy.aria.core.download; /** diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/SingleThreadTask.java b/Aria/src/main/java/com/arialyy/aria/core/download/SingleThreadTask.java index 71f4836b..b3a7d2a0 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/SingleThreadTask.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/SingleThreadTask.java @@ -72,7 +72,7 @@ final class SingleThreadTask implements Runnable { conn.setRequestProperty("Range", "bytes=" + mConfigEntity.START_LOCATION + "-" + mConfigEntity.END_LOCATION); } else { - Log.w(TAG, "该下载不支持断点,即将重新下载"); + Log.w(TAG, "该下载不支持断点"); } conn = ConnectionHelp.setConnectParam(mConfigEntity.DOWNLOAD_TASK_ENTITY, conn); conn.setConnectTimeout(mConstance.CONNECT_TIME_OUT); diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/IEntity.java b/Aria/src/main/java/com/arialyy/aria/core/inf/IEntity.java index 59d3ee4b..992d21a5 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/inf/IEntity.java +++ b/Aria/src/main/java/com/arialyy/aria/core/inf/IEntity.java @@ -25,23 +25,23 @@ public interface IEntity { /** * 其它状态 */ - @Ignore public static final int STATE_OTHER = -1; + @Ignore public static final int STATE_OTHER = -1; /** * 失败状态 */ - @Ignore public static final int STATE_FAIL = 0; + @Ignore public static final int STATE_FAIL = 0; /** * 完成状态 */ - @Ignore public static final int STATE_COMPLETE = 1; + @Ignore public static final int STATE_COMPLETE = 1; /** * 停止状态 */ - @Ignore public static final int STATE_STOP = 2; + @Ignore public static final int STATE_STOP = 2; /** * 未开始状态 */ - @Ignore public static final int STATE_WAIT = 3; + @Ignore public static final int STATE_WAIT = 3; /** * 下载中 */ @@ -49,16 +49,15 @@ public interface IEntity { /** * 预处理 */ - @Ignore public static final int STATE_PRE = 5; + @Ignore public static final int STATE_PRE = 5; /** * 预处理完成 */ - @Ignore public static final int STATE_POST_PRE = 6; + @Ignore public static final int STATE_POST_PRE = 6; /** * 取消下载 */ - @Ignore public static final int STATE_CANCEL = 7; + @Ignore public static final int STATE_CANCEL = 7; public int getState(); - } diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/ITask.java b/Aria/src/main/java/com/arialyy/aria/core/inf/ITask.java index ecb6cfe2..9e464224 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/inf/ITask.java +++ b/Aria/src/main/java/com/arialyy/aria/core/inf/ITask.java @@ -28,6 +28,7 @@ public interface ITask { /** * 是否真正执行 + * * @return true,正在执行; */ public boolean isRunning(); diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/TaskFactory.java b/Aria/src/main/java/com/arialyy/aria/core/queue/TaskFactory.java index 02af9e32..34b6f043 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/queue/TaskFactory.java +++ b/Aria/src/main/java/com/arialyy/aria/core/queue/TaskFactory.java @@ -57,13 +57,14 @@ public class TaskFactory { * @param {@link DownloadSchedulers} * @return {@link DownloadTask}、{@link UploadTask} */ - ITask createTask( - String targetName, ENTITY entity, SCHEDULER schedulers) { + 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; + } + return null; } /** 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 index 7d9e0205..9b7c061a 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/queue/UploadTaskQueue.java +++ b/Aria/src/main/java/com/arialyy/aria/core/queue/UploadTaskQueue.java @@ -42,7 +42,6 @@ public class UploadTaskQueue extends AbsTaskQueue 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 final long TIME_OUT = 1000; - private Map mCacheArray; + private static final String TAG = "CachePool"; + private static final Object LOCK = new Object(); + private static final int MAX_NUM = Integer.MAX_VALUE; //最大下载任务数 + private static final long TIME_OUT = 1000; + private Map mCacheArray; private LinkedBlockingQueue mCacheQueue; public CachePool() { @@ -110,7 +110,7 @@ public class CachePool implements IPool { Log.e(TAG, "请传入有效的下载链接"); return false; } - String key = CommonUtil.keyToHashKey(downloadUrl); + String key = CommonUtil.keyToHashKey(downloadUrl); TASK task = mCacheArray.get(key); mCacheArray.remove(key); return mCacheQueue.remove(task); diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/pool/IPool.java b/Aria/src/main/java/com/arialyy/aria/core/queue/pool/IPool.java index 31a19462..53378e9c 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/queue/pool/IPool.java +++ b/Aria/src/main/java/com/arialyy/aria/core/queue/pool/IPool.java @@ -14,7 +14,6 @@ * limitations under the License. */ - 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 382d547b..d7cab16d 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 @@ -34,14 +34,14 @@ import java.util.concurrent.ConcurrentHashMap; */ public class DownloadSchedulers implements ISchedulers { - private static final String TAG = "DownloadSchedulers"; - private static final Object LOCK = new Object(); + private static final String TAG = "DownloadSchedulers"; + private static final Object LOCK = new Object(); private static volatile DownloadSchedulers INSTANCE = null; /** * 下载器任务监听 */ - private Map> mSchedulerListeners = + private Map> mSchedulerListeners = new ConcurrentHashMap<>(); private DownloadTaskQueue mQueue; @@ -59,16 +59,17 @@ public class DownloadSchedulers implements ISchedulers { } @Override public void addSchedulerListener(String targetName, - OnSchedulerListener schedulerListener) { - mSchedulerListeners.put(targetName, schedulerListener); + ISchedulerListener schedulerListener) { + mSchedulerListeners.put(targetName, + (IDownloadSchedulerListener) schedulerListener); } @Override public void removeSchedulerListener(String targetName, - OnSchedulerListener schedulerListener) { + ISchedulerListener 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(); } } @@ -118,7 +119,8 @@ public class DownloadSchedulers implements ISchedulers { } } - private void callback(int state, DownloadTask task, OnSchedulerListener listener) { + private void callback(int state, DownloadTask task, + IDownloadSchedulerListener listener) { if (listener != null) { if (task == null) { Log.e(TAG, "TASK 为null,回调失败"); @@ -149,6 +151,9 @@ public class DownloadSchedulers implements ISchedulers { case FAIL: listener.onTaskFail(task); break; + case SUPPORT_BREAK_POINT: + listener.onNoSupportBreakPoint(task); + break; } } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/scheduler/IDownloadSchedulerListener.java b/Aria/src/main/java/com/arialyy/aria/core/scheduler/IDownloadSchedulerListener.java new file mode 100644 index 00000000..53ecf709 --- /dev/null +++ b/Aria/src/main/java/com/arialyy/aria/core/scheduler/IDownloadSchedulerListener.java @@ -0,0 +1,29 @@ +/* + * 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 com.arialyy.aria.core.inf.ITask; + +/** + * Created by Aria.Lao on 2017/4/5. + */ +public interface IDownloadSchedulerListener extends ISchedulerListener { + + /** + * 支持断点的回调 + */ + public void onNoSupportBreakPoint(TASK task); +} diff --git a/Aria/src/main/java/com/arialyy/aria/core/scheduler/OnSchedulerListener.java b/Aria/src/main/java/com/arialyy/aria/core/scheduler/ISchedulerListener.java similarity index 95% rename from Aria/src/main/java/com/arialyy/aria/core/scheduler/OnSchedulerListener.java rename to Aria/src/main/java/com/arialyy/aria/core/scheduler/ISchedulerListener.java index d27fcf67..8bb54b2e 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/scheduler/OnSchedulerListener.java +++ b/Aria/src/main/java/com/arialyy/aria/core/scheduler/ISchedulerListener.java @@ -20,7 +20,7 @@ import com.arialyy.aria.core.inf.ITask; /** * Target处理任务监听 */ -public interface OnSchedulerListener { +public interface ISchedulerListener { /** * 任务预加载 */ diff --git a/Aria/src/main/java/com/arialyy/aria/core/scheduler/ISchedulers.java b/Aria/src/main/java/com/arialyy/aria/core/scheduler/ISchedulers.java index f05b7a5b..908d0861 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/scheduler/ISchedulers.java +++ b/Aria/src/main/java/com/arialyy/aria/core/scheduler/ISchedulers.java @@ -17,7 +17,6 @@ package com.arialyy.aria.core.scheduler; import android.os.Handler; -import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.inf.ITask; /** @@ -25,6 +24,10 @@ import com.arialyy.aria.core.inf.ITask; * 调度器功能接口 */ public interface ISchedulers extends Handler.Callback { + /** + * 断点支持 + */ + public static final int SUPPORT_BREAK_POINT = 8; /** * 任务预加载 */ @@ -62,14 +65,14 @@ public interface ISchedulers extends Handler.Callback { * 注册下载器监听,一个观察者只能注册一次监听 * * @param targetName 观察者,创建该监听器的对象类名 - * @param schedulerListener {@link OnSchedulerListener} + * @param schedulerListener {@link ISchedulerListener} */ - public void addSchedulerListener(String targetName, OnSchedulerListener schedulerListener); + public void addSchedulerListener(String targetName, ISchedulerListener schedulerListener); /** * @param targetName 观察者,创建该监听器的对象类名 * 取消注册监听器 */ - public void removeSchedulerListener(String targetName, OnSchedulerListener schedulerListener); - + public void removeSchedulerListener(String targetName, + ISchedulerListener schedulerListener); } \ 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 index 2dc0b6fa..b5108f6b 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/scheduler/UploadSchedulers.java +++ b/Aria/src/main/java/com/arialyy/aria/core/scheduler/UploadSchedulers.java @@ -33,12 +33,10 @@ import java.util.concurrent.ConcurrentHashMap; * 上传任务调度器 */ 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 = + 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; @@ -57,15 +55,15 @@ public class UploadSchedulers implements ISchedulers { } @Override public void addSchedulerListener(String targetName, - OnSchedulerListener schedulerListener) { + ISchedulerListener schedulerListener) { mSchedulerListeners.put(targetName, schedulerListener); } @Override public void removeSchedulerListener(String targetName, - OnSchedulerListener schedulerListener) { - for (Iterator>> iter = + ISchedulerListener schedulerListener) { + 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(); } } @@ -124,7 +122,7 @@ public class UploadSchedulers implements ISchedulers { } } - private void callback(int state, UploadTask task, OnSchedulerListener listener) { + private void callback(int state, UploadTask task, ISchedulerListener listener) { if (listener != null) { if (task == null) { Log.e(TAG, "TASK 为null,回调失败"); 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 051b16d4..dd4a54eb 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,3 +1,18 @@ +/* + * 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.Parcel; diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadListener.java b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadListener.java index 7d13a84b..94dce03d 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadListener.java +++ b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadListener.java @@ -1,10 +1,25 @@ +/* + * 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; /** * Created by Aria.Lao on 2017/2/23. */ -public class UploadListener implements IUploadListener{ +public class UploadListener implements IUploadListener { @Override public void onPre() { } diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadReceiver.java b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadReceiver.java index 80b70cfa..848843b5 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadReceiver.java +++ b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadReceiver.java @@ -16,13 +16,12 @@ package com.arialyy.aria.core.upload; import android.support.annotation.NonNull; -import android.util.Log; import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.command.AbsCmd; import com.arialyy.aria.core.command.CmdFactory; import com.arialyy.aria.core.inf.IEntity; import com.arialyy.aria.core.inf.IReceiver; -import com.arialyy.aria.core.scheduler.OnSchedulerListener; +import com.arialyy.aria.core.scheduler.ISchedulerListener; import com.arialyy.aria.core.scheduler.UploadSchedulers; import com.arialyy.aria.orm.DbEntity; import com.arialyy.aria.util.CheckUtil; @@ -30,7 +29,6 @@ import com.arialyy.aria.util.CommonUtil; import java.util.ArrayList; import java.util.List; import java.util.Set; -import java.util.regex.Matcher; import java.util.regex.Pattern; /** @@ -40,7 +38,7 @@ import java.util.regex.Pattern; public class UploadReceiver implements IReceiver { private static final String TAG = "DownloadReceiver"; public String targetName; - public OnSchedulerListener listener; + public ISchedulerListener listener; /** * 加载任务 @@ -118,7 +116,7 @@ public class UploadReceiver implements IReceiver { /** * 添加调度器回调 */ - public UploadReceiver addSchedulerListener(OnSchedulerListener listener) { + public UploadReceiver addSchedulerListener(ISchedulerListener listener) { this.listener = listener; UploadSchedulers.getInstance().addSchedulerListener(targetName, listener); return this; 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 436516b0..d35109b8 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,3 +1,18 @@ +/* + * 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.content.Intent; @@ -57,7 +72,6 @@ public class UploadTask implements ITask { } @Override public void start() { - Log.d(TAG, "task_start"); if (mUtil.isRunning()) { Log.d(TAG, "任务正在下载"); } else { @@ -206,14 +220,13 @@ public class UploadTask implements ITask { entity.setComplete(action.equals(Aria.ACTION_COMPLETE)); entity.setCurrentProgress(location); entity.update(); + if (!Configuration.isOpenBreadCast) return; 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); - } + AriaManager.APP.sendBroadcast(intent); } } 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 be264f97..1b05b200 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 @@ -59,7 +59,6 @@ final class UploadUtil implements Runnable { } public void start() { - Log.d(TAG, "start"); isCancel = false; isRunning = false; new Thread(this).start(); @@ -71,7 +70,6 @@ final class UploadUtil implements Runnable { } @Override public void run() { - Log.e(TAG, "run"); File uploadFile = new File(mUploadEntity.getFilePath()); if (!uploadFile.exists()) { Log.e(TAG, "【" + mUploadEntity.getFilePath() + "】,文件不存在。"); @@ -123,7 +121,14 @@ final class UploadUtil implements Runnable { } private void fail() { - mListener.onFail(); + try { + mListener.onFail(); + if (mOutputStream != null) { + mOutputStream.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } } /** @@ -151,7 +156,6 @@ final class UploadUtil implements Runnable { */ private void uploadFile(PrintWriter writer, String attachment, File uploadFile) throws IOException { - Log.e(TAG, "uploadFile"); writer.append(PREFIX).append(BOUNDARY).append(LINE_END); writer.append("Content-Disposition: form-data; name=\"") .append(attachment) diff --git a/Aria/src/main/java/com/arialyy/aria/exception/FileException.java b/Aria/src/main/java/com/arialyy/aria/exception/FileException.java index f4fbb700..734b2ead 100644 --- a/Aria/src/main/java/com/arialyy/aria/exception/FileException.java +++ b/Aria/src/main/java/com/arialyy/aria/exception/FileException.java @@ -1,3 +1,18 @@ +/* + * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.arialyy.aria.exception; /** diff --git a/Aria/src/main/java/com/arialyy/aria/orm/DbEntity.java b/Aria/src/main/java/com/arialyy/aria/orm/DbEntity.java index c1dfbe08..e39df929 100644 --- a/Aria/src/main/java/com/arialyy/aria/orm/DbEntity.java +++ b/Aria/src/main/java/com/arialyy/aria/orm/DbEntity.java @@ -27,9 +27,9 @@ import java.util.List; * 所有数据库实体父类 */ public class DbEntity { - private static final Object LOCK = new Object(); - protected int rowID = -1; - private DbUtil mUtil = DbUtil.getInstance(); + private static final Object LOCK = new Object(); + protected int rowID = -1; + private DbUtil mUtil = DbUtil.getInstance(); protected DbEntity() { @@ -75,7 +75,7 @@ public class DbEntity { * @return 没有数据返回null */ public static T findData(Class clazz, String... expression) { - DbUtil util = DbUtil.getInstance(); + DbUtil util = DbUtil.getInstance(); List datas = util.findData(clazz, expression); return datas == null ? null : datas.size() > 0 ? datas.get(0) : null; } @@ -150,15 +150,15 @@ public class DbEntity { private T findData(Class clazz, @NonNull String[] wheres, @NonNull String[] values) { - DbUtil util = DbUtil.getInstance(); + DbUtil util = DbUtil.getInstance(); List list = util.findData(clazz, wheres, values); return list == null ? null : list.get(0); } private void updateRowID() { try { - Field[] fields = CommonUtil.getFields(getClass()); - List where = new ArrayList<>(); + Field[] fields = CommonUtil.getFields(getClass()); + List where = new ArrayList<>(); List values = new ArrayList<>(); for (Field field : fields) { field.setAccessible(true); diff --git a/Aria/src/main/java/com/arialyy/aria/orm/DbUtil.java b/Aria/src/main/java/com/arialyy/aria/orm/DbUtil.java index 10b64600..443bd98d 100644 --- a/Aria/src/main/java/com/arialyy/aria/orm/DbUtil.java +++ b/Aria/src/main/java/com/arialyy/aria/orm/DbUtil.java @@ -34,19 +34,19 @@ import java.util.List; * 数据库操作工具 */ public class DbUtil { - private static final String TAG = "DbUtil"; - private static final Object LOCK = new Object(); - private volatile static DbUtil INSTANCE = null; - private int CREATE_TABLE = 0; - private int TABLE_EXISTS = 1; - private int INSERT_DATA = 2; - private int MODIFY_DATA = 3; - private int FIND_DATA = 4; - private int FIND_ALL_DATA = 5; - private int DEL_DATA = 6; - private int ROW_ID = 7; + private static final String TAG = "DbUtil"; + private static final Object LOCK = new Object(); + private volatile static DbUtil INSTANCE = null; + private int CREATE_TABLE = 0; + private int TABLE_EXISTS = 1; + private int INSERT_DATA = 2; + private int MODIFY_DATA = 3; + private int FIND_DATA = 4; + private int FIND_ALL_DATA = 5; + private int DEL_DATA = 6; + private int ROW_ID = 7; private SQLiteDatabase mDb; - private SqlHelper mHelper; + private SqlHelper mHelper; private DbUtil() { @@ -123,8 +123,8 @@ public class DbUtil { */ synchronized void modifyData(DbEntity dbEntity) { mDb = mHelper.getWritableDatabase(); - Class clazz = dbEntity.getClass(); - Field[] fields = CommonUtil.getFields(clazz); + Class clazz = dbEntity.getClass(); + Field[] fields = CommonUtil.getFields(clazz); if (fields != null && fields.length > 0) { StringBuilder sb = new StringBuilder(); sb.append("UPDATE ").append(CommonUtil.getClassName(dbEntity)).append(" SET "); @@ -398,8 +398,8 @@ public class DbUtil { synchronized int[] getRowId(Class clazz) { mDb = mHelper.getReadableDatabase(); Cursor cursor = mDb.rawQuery("SELECT rowid, * FROM " + CommonUtil.getClassName(clazz), null); - int[] ids = new int[cursor.getCount()]; - int i = 0; + int[] ids = new int[cursor.getCount()]; + int i = 0; while (cursor.moveToNext()) { ids[i] = cursor.getInt(cursor.getColumnIndex("rowid")); i++; @@ -430,8 +430,8 @@ public class DbUtil { i++; } print(ROW_ID, sb.toString()); - Cursor c = mDb.rawQuery(sb.toString(), null); - int id = c.getColumnIndex("rowid"); + Cursor c = mDb.rawQuery(sb.toString(), null); + int id = c.getColumnIndex("rowid"); c.close(); close(); return id; @@ -442,7 +442,7 @@ public class DbUtil { */ private synchronized List newInstanceEntity(Class clazz, Cursor cursor) { - Field[] fields = CommonUtil.getFields(clazz); + Field[] fields = CommonUtil.getFields(clazz); List entitys = new ArrayList<>(); if (fields != null && fields.length > 0) { try { @@ -453,8 +453,8 @@ public class DbUtil { if (ignoreField(field)) { continue; } - Class type = field.getType(); - int column = cursor.getColumnIndex(field.getName()); + Class type = field.getType(); + int column = cursor.getColumnIndex(field.getName()); if (type == String.class) { field.set(entity, cursor.getString(column)); } else if (type == int.class || type == Integer.class) { diff --git a/Aria/src/main/java/com/arialyy/aria/orm/Id.java b/Aria/src/main/java/com/arialyy/aria/orm/Id.java index e6861025..a59b85d9 100644 --- a/Aria/src/main/java/com/arialyy/aria/orm/Id.java +++ b/Aria/src/main/java/com/arialyy/aria/orm/Id.java @@ -14,7 +14,6 @@ * limitations under the License. */ - package com.arialyy.aria.orm; import java.lang.annotation.ElementType; diff --git a/Aria/src/main/java/com/arialyy/aria/orm/Ignore.java b/Aria/src/main/java/com/arialyy/aria/orm/Ignore.java index 1b3c1359..33c4523f 100644 --- a/Aria/src/main/java/com/arialyy/aria/orm/Ignore.java +++ b/Aria/src/main/java/com/arialyy/aria/orm/Ignore.java @@ -14,7 +14,6 @@ * limitations under the License. */ - package com.arialyy.aria.orm; import java.lang.annotation.ElementType; diff --git a/Aria/src/main/java/com/arialyy/aria/orm/SqlHelper.java b/Aria/src/main/java/com/arialyy/aria/orm/SqlHelper.java index 4ab30b02..211d8e1e 100644 --- a/Aria/src/main/java/com/arialyy/aria/orm/SqlHelper.java +++ b/Aria/src/main/java/com/arialyy/aria/orm/SqlHelper.java @@ -14,7 +14,6 @@ * limitations under the License. */ - package com.arialyy.aria.orm; import android.content.Context; diff --git a/Aria/src/main/java/com/arialyy/aria/util/BufferedRandomAccessFile.java b/Aria/src/main/java/com/arialyy/aria/util/BufferedRandomAccessFile.java index edc863ed..25431082 100644 --- a/Aria/src/main/java/com/arialyy/aria/util/BufferedRandomAccessFile.java +++ b/Aria/src/main/java/com/arialyy/aria/util/BufferedRandomAccessFile.java @@ -41,9 +41,9 @@ import java.util.Arrays; public final class BufferedRandomAccessFile extends RandomAccessFile { //private static final Logger logger_ = Logger.getLogger(BufferedRandomAccessFile.class); - static final int LogBuffSz_ = 16; // 64K buffer - public static final int BuffSz_ = (1 << LogBuffSz_); - static final long BuffMask_ = ~(((long) BuffSz_) - 1L); + static final int LogBuffSz_ = 16; // 64K buffer + public static final int BuffSz_ = (1 << LogBuffSz_); + static final long BuffMask_ = ~(((long) BuffSz_) - 1L); /* * This implementation is based on the buffer implementation in Modula-3's @@ -51,12 +51,12 @@ public final class BufferedRandomAccessFile extends RandomAccessFile { */ private boolean dirty_; // true iff unflushed bytes exist private boolean closed_; // true iff the file is closed - private long curr_; // current position in file - private long lo_, hi_; // bounds on characters in "buff" - private byte[] buff_; // local buffer - private long maxHi_; // this.lo + this.buff.length + private long curr_; // current position in file + private long lo_, hi_; // bounds on characters in "buff" + private byte[] buff_; // local buffer + private long maxHi_; // this.lo + this.buff.length private boolean hitEOF_; // buffer contains last file block? - private long diskPos_; // disk position + private long diskPos_; // disk position /* * To describe the above fields, we introduce the following abstractions for diff --git a/Aria/src/main/java/com/arialyy/aria/util/CheckUtil.java b/Aria/src/main/java/com/arialyy/aria/util/CheckUtil.java index 25608e5e..b9ed6838 100644 --- a/Aria/src/main/java/com/arialyy/aria/util/CheckUtil.java +++ b/Aria/src/main/java/com/arialyy/aria/util/CheckUtil.java @@ -103,6 +103,8 @@ public class CheckUtil { throw new NullPointerException("下载实体不能为空"); } else if (TextUtils.isEmpty(entity1.getDownloadUrl())) { throw new IllegalArgumentException("下载链接不能为空"); + } else if (TextUtils.isEmpty(entity1.getDownloadPath())) { + throw new IllegalArgumentException("保存路径不能为空"); } } else if (entity instanceof UploadTaskEntity) { UploadEntity entity1 = ((UploadTaskEntity) entity).uploadEntity; diff --git a/Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java b/Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java index 34843364..47c59018 100644 --- a/Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java +++ b/Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java @@ -50,7 +50,7 @@ public class CommonUtil { public static Intent createIntent(String packageName, String action) { Uri.Builder builder = new Uri.Builder(); builder.scheme(packageName); - Uri uri = builder.build(); + Uri uri = builder.build(); Intent intent = new Intent(action); intent.setData(uri); return intent; @@ -65,7 +65,7 @@ public class CommonUtil { * @return 成功标志 */ public static Boolean putString(String preName, Context context, String key, String value) { - SharedPreferences pre = context.getSharedPreferences(preName, Context.MODE_PRIVATE); + SharedPreferences pre = context.getSharedPreferences(preName, Context.MODE_PRIVATE); SharedPreferences.Editor editor = pre.edit(); editor.putString(key, value); return editor.commit(); @@ -298,9 +298,9 @@ public class CommonUtil { * 读取下载配置文件 */ public static Properties loadConfig(File file) { - Properties properties = new Properties(); - FileInputStream fis = null; - if (!file.exists()){ + Properties properties = new Properties(); + FileInputStream fis = null; + if (!file.exists()) { createFile(file.getPath()); } try { diff --git a/Aria/src/main/java/com/arialyy/aria/util/FileUtil.java b/Aria/src/main/java/com/arialyy/aria/util/FileUtil.java index 9dcf77c6..6fb9bf09 100644 --- a/Aria/src/main/java/com/arialyy/aria/util/FileUtil.java +++ b/Aria/src/main/java/com/arialyy/aria/util/FileUtil.java @@ -1,3 +1,18 @@ +/* + * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.arialyy.aria.util; import android.content.Context; @@ -60,7 +75,8 @@ public class FileUtil { || exName.equalsIgnoreCase("rm") || exName.equalsIgnoreCase("rmvb")) { //fType = new FileType("视频", ); - } return fType; + } + return fType; } /** diff --git a/Aria/src/main/java/com/arialyy/aria/util/PathUtil.java b/Aria/src/main/java/com/arialyy/aria/util/PathUtil.java index ed7efc5a..b0e5aad3 100644 --- a/Aria/src/main/java/com/arialyy/aria/util/PathUtil.java +++ b/Aria/src/main/java/com/arialyy/aria/util/PathUtil.java @@ -14,7 +14,6 @@ * limitations under the License. */ - package com.arialyy.aria.util; import android.os.Environment; diff --git a/Aria/src/main/java/com/arialyy/aria/util/Speed.java b/Aria/src/main/java/com/arialyy/aria/util/Speed.java index 4a069336..f26a2329 100644 --- a/Aria/src/main/java/com/arialyy/aria/util/Speed.java +++ b/Aria/src/main/java/com/arialyy/aria/util/Speed.java @@ -1,3 +1,18 @@ +/* + * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.arialyy.aria.util; /** @@ -7,20 +22,16 @@ public enum Speed { /** * 最大速度为256kb */ - KB_256(64), - /** + KB_256(64), /** * 最大速度为512kb */ - KB_512(128), - /** + KB_512(128), /** * 最大速度为1mb */ - MB_1(256), - /** + MB_1(256), /** * 最大速度为2mb */ - MB_2(1024), - /** + MB_2(1024), /** * 最大速度为10mb */ MAX(8192); diff --git a/Aria/src/main/java/com/arialyy/aria/util/WeakHandler.java b/Aria/src/main/java/com/arialyy/aria/util/WeakHandler.java index 2d176dde..55a334ab 100644 --- a/Aria/src/main/java/com/arialyy/aria/util/WeakHandler.java +++ b/Aria/src/main/java/com/arialyy/aria/util/WeakHandler.java @@ -47,467 +47,451 @@ import java.util.concurrent.locks.ReentrantLock; * * Created by Dmytro Voronkevych on 17/06/2014. */ -@SuppressWarnings("unused") -public class WeakHandler { - private final Handler.Callback mCallback; // hard reference to Callback. We need to keep callback in memory - private final ExecHandler mExec; - private Lock mLock = new ReentrantLock(); - @SuppressWarnings("ConstantConditions") - @VisibleForTesting - final ChainedRef mRunnables = new ChainedRef(mLock, null); - - /** - * Default constructor associates this handler with the {@link Looper} for the - * current thread. - * - * If this thread does not have a looper, this handler won't be able to receive messages - * so an exception is thrown. - */ - public WeakHandler() { - mCallback = null; - mExec = new ExecHandler(); +@SuppressWarnings("unused") public class WeakHandler { + private final Handler.Callback mCallback; + // hard reference to Callback. We need to keep callback in memory + private final ExecHandler mExec; + private Lock mLock = new ReentrantLock(); + @SuppressWarnings("ConstantConditions") @VisibleForTesting final ChainedRef mRunnables = + new ChainedRef(mLock, null); + + /** + * Default constructor associates this handler with the {@link Looper} for the + * current thread. + * + * If this thread does not have a looper, this handler won't be able to receive messages + * so an exception is thrown. + */ + public WeakHandler() { + mCallback = null; + mExec = new ExecHandler(); + } + + /** + * Constructor associates this handler with the {@link Looper} for the + * current thread and takes a callback interface in which you can handle + * messages. + * + * If this thread does not have a looper, this handler won't be able to receive messages + * so an exception is thrown. + * + * @param callback The callback interface in which to handle messages, or null. + */ + public WeakHandler(@Nullable Handler.Callback callback) { + mCallback = callback; // Hard referencing body + mExec = new ExecHandler(new WeakReference<>(callback)); // Weak referencing inside ExecHandler + } + + /** + * Use the provided {@link Looper} instead of the default one. + * + * @param looper The looper, must not be null. + */ + public WeakHandler(@NonNull Looper looper) { + mCallback = null; + mExec = new ExecHandler(looper); + } + + /** + * Use the provided {@link Looper} instead of the default one and take a callback + * interface in which to handle messages. + * + * @param looper The looper, must not be null. + * @param callback The callback interface in which to handle messages, or null. + */ + public WeakHandler(@NonNull Looper looper, @NonNull Handler.Callback callback) { + mCallback = callback; + mExec = new ExecHandler(looper, new WeakReference<>(callback)); + } + + /** + * Causes the Runnable r to be added to the message queue. + * The runnable will be run on the thread to which this handler is + * attached. + * + * @param r The Runnable that will be executed. + * @return Returns true if the Runnable was successfully placed in to the + * message queue. Returns false on failure, usually because the + * looper processing the message queue is exiting. + */ + public final boolean post(@NonNull Runnable r) { + return mExec.post(wrapRunnable(r)); + } + + /** + * Causes the Runnable r to be added to the message queue, to be run + * at a specific time given by uptimeMillis. + * The time-base is {@link android.os.SystemClock#uptimeMillis}. + * The runnable will be run on the thread to which this handler is attached. + * + * @param r The Runnable that will be executed. + * @param uptimeMillis The absolute time at which the callback should run, + * using the {@link android.os.SystemClock#uptimeMillis} time-base. + * @return Returns true if the Runnable was successfully placed in to the + * message queue. Returns false on failure, usually because the + * looper processing the message queue is exiting. Note that a + * result of true does not mean the Runnable will be processed -- if + * the looper is quit before the delivery time of the message + * occurs then the message will be dropped. + */ + public final boolean postAtTime(@NonNull Runnable r, long uptimeMillis) { + return mExec.postAtTime(wrapRunnable(r), uptimeMillis); + } + + /** + * Causes the Runnable r to be added to the message queue, to be run + * at a specific time given by uptimeMillis. + * The time-base is {@link android.os.SystemClock#uptimeMillis}. + * The runnable will be run on the thread to which this handler is attached. + * + * @param r The Runnable that will be executed. + * @param uptimeMillis The absolute time at which the callback should run, + * using the {@link android.os.SystemClock#uptimeMillis} time-base. + * @return Returns true if the Runnable was successfully placed in to the + * message queue. Returns false on failure, usually because the + * looper processing the message queue is exiting. Note that a + * result of true does not mean the Runnable will be processed -- if + * the looper is quit before the delivery time of the message + * occurs then the message will be dropped. + * @see android.os.SystemClock#uptimeMillis + */ + public final boolean postAtTime(Runnable r, Object token, long uptimeMillis) { + return mExec.postAtTime(wrapRunnable(r), token, uptimeMillis); + } + + /** + * Causes the Runnable r to be added to the message queue, to be run + * after the specified amount of time elapses. + * The runnable will be run on the thread to which this handler + * is attached. + * + * @param r The Runnable that will be executed. + * @param delayMillis The delay (in milliseconds) until the Runnable + * will be executed. + * @return Returns true if the Runnable was successfully placed in to the + * message queue. Returns false on failure, usually because the + * looper processing the message queue is exiting. Note that a + * result of true does not mean the Runnable will be processed -- + * if the looper is quit before the delivery time of the message + * occurs then the message will be dropped. + */ + public final boolean postDelayed(Runnable r, long delayMillis) { + return mExec.postDelayed(wrapRunnable(r), delayMillis); + } + + /** + * Posts a message to an object that implements Runnable. + * Causes the Runnable r to executed on the next iteration through the + * message queue. The runnable will be run on the thread to which this + * handler is attached. + * This method is only for use in very special circumstances -- it + * can easily starve the message queue, cause ordering problems, or have + * other unexpected side-effects. + * + * @param r The Runnable that will be executed. + * @return Returns true if the message was successfully placed in to the + * message queue. Returns false on failure, usually because the + * looper processing the message queue is exiting. + */ + public final boolean postAtFrontOfQueue(Runnable r) { + return mExec.postAtFrontOfQueue(wrapRunnable(r)); + } + + /** + * Remove any pending posts of Runnable r that are in the message queue. + */ + public final void removeCallbacks(Runnable r) { + final WeakRunnable runnable = mRunnables.remove(r); + if (runnable != null) { + mExec.removeCallbacks(runnable); } - - /** - * Constructor associates this handler with the {@link Looper} for the - * current thread and takes a callback interface in which you can handle - * messages. - * - * If this thread does not have a looper, this handler won't be able to receive messages - * so an exception is thrown. - * - * @param callback The callback interface in which to handle messages, or null. - */ - public WeakHandler(@Nullable Handler.Callback callback) { - mCallback = callback; // Hard referencing body - mExec = new ExecHandler(new WeakReference<>(callback)); // Weak referencing inside ExecHandler - } - - /** - * Use the provided {@link Looper} instead of the default one. - * - * @param looper The looper, must not be null. - */ - public WeakHandler(@NonNull Looper looper) { - mCallback = null; - mExec = new ExecHandler(looper); + } + + /** + * Remove any pending posts of Runnable r with Object + * token that are in the message queue. If token is null, + * all callbacks will be removed. + */ + public final void removeCallbacks(Runnable r, Object token) { + final WeakRunnable runnable = mRunnables.remove(r); + if (runnable != null) { + mExec.removeCallbacks(runnable, token); } - - /** - * Use the provided {@link Looper} instead of the default one and take a callback - * interface in which to handle messages. - * - * @param looper The looper, must not be null. - * @param callback The callback interface in which to handle messages, or null. - */ - public WeakHandler(@NonNull Looper looper, @NonNull Handler.Callback callback) { - mCallback = callback; - mExec = new ExecHandler(looper, new WeakReference<>(callback)); - } - - /** - * Causes the Runnable r to be added to the message queue. - * The runnable will be run on the thread to which this handler is - * attached. - * - * @param r The Runnable that will be executed. - * - * @return Returns true if the Runnable was successfully placed in to the - * message queue. Returns false on failure, usually because the - * looper processing the message queue is exiting. - */ - public final boolean post(@NonNull Runnable r) { - return mExec.post(wrapRunnable(r)); + } + + /** + * Pushes a message onto the end of the message queue after all pending messages + * before the current time. It will be received in callback, + * in the thread attached to this handler. + * + * @return Returns true if the message was successfully placed in to the + * message queue. Returns false on failure, usually because the + * looper processing the message queue is exiting. + */ + public final boolean sendMessage(Message msg) { + return mExec.sendMessage(msg); + } + + /** + * Sends a Message containing only the what value. + * + * @return Returns true if the message was successfully placed in to the + * message queue. Returns false on failure, usually because the + * looper processing the message queue is exiting. + */ + public final boolean sendEmptyMessage(int what) { + return mExec.sendEmptyMessage(what); + } + + /** + * Sends a Message containing only the what value, to be delivered + * after the specified amount of time elapses. + * + * @return Returns true if the message was successfully placed in to the + * message queue. Returns false on failure, usually because the + * looper processing the message queue is exiting. + * @see #sendMessageDelayed(android.os.Message, long) + */ + public final boolean sendEmptyMessageDelayed(int what, long delayMillis) { + return mExec.sendEmptyMessageDelayed(what, delayMillis); + } + + /** + * Sends a Message containing only the what value, to be delivered + * at a specific time. + * + * @return Returns true if the message was successfully placed in to the + * message queue. Returns false on failure, usually because the + * looper processing the message queue is exiting. + * @see #sendMessageAtTime(android.os.Message, long) + */ + public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) { + return mExec.sendEmptyMessageAtTime(what, uptimeMillis); + } + + /** + * Enqueue a message into the message queue after all pending messages + * before (current time + delayMillis). You will receive it in + * callback, in the thread attached to this handler. + * + * @return Returns true if the message was successfully placed in to the + * message queue. Returns false on failure, usually because the + * looper processing the message queue is exiting. Note that a + * result of true does not mean the message will be processed -- if + * the looper is quit before the delivery time of the message + * occurs then the message will be dropped. + */ + public final boolean sendMessageDelayed(Message msg, long delayMillis) { + return mExec.sendMessageDelayed(msg, delayMillis); + } + + /** + * Enqueue a message into the message queue after all pending messages + * before the absolute time (in milliseconds) uptimeMillis. + * The time-base is {@link android.os.SystemClock#uptimeMillis}. + * You will receive it in callback, in the thread attached + * to this handler. + * + * @param uptimeMillis The absolute time at which the message should be + * delivered, using the + * {@link android.os.SystemClock#uptimeMillis} time-base. + * @return Returns true if the message was successfully placed in to the + * message queue. Returns false on failure, usually because the + * looper processing the message queue is exiting. Note that a + * result of true does not mean the message will be processed -- if + * the looper is quit before the delivery time of the message + * occurs then the message will be dropped. + */ + public boolean sendMessageAtTime(Message msg, long uptimeMillis) { + return mExec.sendMessageAtTime(msg, uptimeMillis); + } + + /** + * Enqueue a message at the front of the message queue, to be processed on + * the next iteration of the message loop. You will receive it in + * callback, in the thread attached to this handler. + * This method is only for use in very special circumstances -- it + * can easily starve the message queue, cause ordering problems, or have + * other unexpected side-effects. + * + * @return Returns true if the message was successfully placed in to the + * message queue. Returns false on failure, usually because the + * looper processing the message queue is exiting. + */ + public final boolean sendMessageAtFrontOfQueue(Message msg) { + return mExec.sendMessageAtFrontOfQueue(msg); + } + + /** + * Remove any pending posts of messages with code 'what' that are in the + * message queue. + */ + public final void removeMessages(int what) { + mExec.removeMessages(what); + } + + /** + * Remove any pending posts of messages with code 'what' and whose obj is + * 'object' that are in the message queue. If object is null, + * all messages will be removed. + */ + public final void removeMessages(int what, Object object) { + mExec.removeMessages(what, object); + } + + /** + * Remove any pending posts of callbacks and sent messages whose + * obj is token. If token is null, + * all callbacks and messages will be removed. + */ + public final void removeCallbacksAndMessages(Object token) { + mExec.removeCallbacksAndMessages(token); + } + + /** + * Check if there are any pending posts of messages with code 'what' in + * the message queue. + */ + public final boolean hasMessages(int what) { + return mExec.hasMessages(what); + } + + /** + * Check if there are any pending posts of messages with code 'what' and + * whose obj is 'object' in the message queue. + */ + public final boolean hasMessages(int what, Object object) { + return mExec.hasMessages(what, object); + } + + public final Looper getLooper() { + return mExec.getLooper(); + } + + private WeakRunnable wrapRunnable(@NonNull Runnable r) { + //noinspection ConstantConditions + if (r == null) { + throw new NullPointerException("Runnable can't be null"); } + final ChainedRef hardRef = new ChainedRef(mLock, r); + mRunnables.insertAfter(hardRef); + return hardRef.wrapper; + } - /** - * Causes the Runnable r to be added to the message queue, to be run - * at a specific time given by uptimeMillis. - * The time-base is {@link android.os.SystemClock#uptimeMillis}. - * The runnable will be run on the thread to which this handler is attached. - * - * @param r The Runnable that will be executed. - * @param uptimeMillis The absolute time at which the callback should run, - * using the {@link android.os.SystemClock#uptimeMillis} time-base. - * - * @return Returns true if the Runnable was successfully placed in to the - * message queue. Returns false on failure, usually because the - * looper processing the message queue is exiting. Note that a - * result of true does not mean the Runnable will be processed -- if - * the looper is quit before the delivery time of the message - * occurs then the message will be dropped. - */ - public final boolean postAtTime(@NonNull Runnable r, long uptimeMillis) { - return mExec.postAtTime(wrapRunnable(r), uptimeMillis); - } + private static class ExecHandler extends Handler { + private final WeakReference mCallback; - /** - * Causes the Runnable r to be added to the message queue, to be run - * at a specific time given by uptimeMillis. - * The time-base is {@link android.os.SystemClock#uptimeMillis}. - * The runnable will be run on the thread to which this handler is attached. - * - * @param r The Runnable that will be executed. - * @param uptimeMillis The absolute time at which the callback should run, - * using the {@link android.os.SystemClock#uptimeMillis} time-base. - * - * @return Returns true if the Runnable was successfully placed in to the - * message queue. Returns false on failure, usually because the - * looper processing the message queue is exiting. Note that a - * result of true does not mean the Runnable will be processed -- if - * the looper is quit before the delivery time of the message - * occurs then the message will be dropped. - * - * @see android.os.SystemClock#uptimeMillis - */ - public final boolean postAtTime(Runnable r, Object token, long uptimeMillis) { - return mExec.postAtTime(wrapRunnable(r), token, uptimeMillis); + ExecHandler() { + mCallback = null; } - /** - * Causes the Runnable r to be added to the message queue, to be run - * after the specified amount of time elapses. - * The runnable will be run on the thread to which this handler - * is attached. - * - * @param r The Runnable that will be executed. - * @param delayMillis The delay (in milliseconds) until the Runnable - * will be executed. - * - * @return Returns true if the Runnable was successfully placed in to the - * message queue. Returns false on failure, usually because the - * looper processing the message queue is exiting. Note that a - * result of true does not mean the Runnable will be processed -- - * if the looper is quit before the delivery time of the message - * occurs then the message will be dropped. - */ - public final boolean postDelayed(Runnable r, long delayMillis) { - return mExec.postDelayed(wrapRunnable(r), delayMillis); + ExecHandler(WeakReference callback) { + mCallback = callback; } - /** - * Posts a message to an object that implements Runnable. - * Causes the Runnable r to executed on the next iteration through the - * message queue. The runnable will be run on the thread to which this - * handler is attached. - * This method is only for use in very special circumstances -- it - * can easily starve the message queue, cause ordering problems, or have - * other unexpected side-effects. - * - * @param r The Runnable that will be executed. - * - * @return Returns true if the message was successfully placed in to the - * message queue. Returns false on failure, usually because the - * looper processing the message queue is exiting. - */ - public final boolean postAtFrontOfQueue(Runnable r) { - return mExec.postAtFrontOfQueue(wrapRunnable(r)); + ExecHandler(Looper looper) { + super(looper); + mCallback = null; } - /** - * Remove any pending posts of Runnable r that are in the message queue. - */ - public final void removeCallbacks(Runnable r) { - final WeakRunnable runnable = mRunnables.remove(r); - if (runnable != null) { - mExec.removeCallbacks(runnable); - } + ExecHandler(Looper looper, WeakReference callback) { + super(looper); + mCallback = callback; } - /** - * Remove any pending posts of Runnable r with Object - * token that are in the message queue. If token is null, - * all callbacks will be removed. - */ - public final void removeCallbacks(Runnable r, Object token) { - final WeakRunnable runnable = mRunnables.remove(r); - if (runnable != null) { - mExec.removeCallbacks(runnable, token); - } + @Override public void handleMessage(@NonNull Message msg) { + if (mCallback == null) { + return; + } + final Handler.Callback callback = mCallback.get(); + if (callback == null) { // Already disposed + return; + } + callback.handleMessage(msg); } + } - /** - * Pushes a message onto the end of the message queue after all pending messages - * before the current time. It will be received in callback, - * in the thread attached to this handler. - * - * @return Returns true if the message was successfully placed in to the - * message queue. Returns false on failure, usually because the - * looper processing the message queue is exiting. - */ - public final boolean sendMessage(Message msg) { - return mExec.sendMessage(msg); - } + static class WeakRunnable implements Runnable { + private final WeakReference mDelegate; + private final WeakReference mReference; - /** - * Sends a Message containing only the what value. - * - * @return Returns true if the message was successfully placed in to the - * message queue. Returns false on failure, usually because the - * looper processing the message queue is exiting. - */ - public final boolean sendEmptyMessage(int what) { - return mExec.sendEmptyMessage(what); + WeakRunnable(WeakReference delegate, WeakReference reference) { + mDelegate = delegate; + mReference = reference; } - /** - * Sends a Message containing only the what value, to be delivered - * after the specified amount of time elapses. - * @see #sendMessageDelayed(android.os.Message, long) - * - * @return Returns true if the message was successfully placed in to the - * message queue. Returns false on failure, usually because the - * looper processing the message queue is exiting. - */ - public final boolean sendEmptyMessageDelayed(int what, long delayMillis) { - return mExec.sendEmptyMessageDelayed(what, delayMillis); + @Override public void run() { + final Runnable delegate = mDelegate.get(); + final ChainedRef reference = mReference.get(); + if (reference != null) { + reference.remove(); + } + if (delegate != null) { + delegate.run(); + } } + } - /** - * Sends a Message containing only the what value, to be delivered - * at a specific time. - * @see #sendMessageAtTime(android.os.Message, long) - * - * @return Returns true if the message was successfully placed in to the - * message queue. Returns false on failure, usually because the - * looper processing the message queue is exiting. - */ - public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) { - return mExec.sendEmptyMessageAtTime(what, uptimeMillis); - } + static class ChainedRef { + @Nullable ChainedRef next; + @Nullable ChainedRef prev; + @NonNull final Runnable runnable; + @NonNull final WeakRunnable wrapper; - /** - * Enqueue a message into the message queue after all pending messages - * before (current time + delayMillis). You will receive it in - * callback, in the thread attached to this handler. - * - * @return Returns true if the message was successfully placed in to the - * message queue. Returns false on failure, usually because the - * looper processing the message queue is exiting. Note that a - * result of true does not mean the message will be processed -- if - * the looper is quit before the delivery time of the message - * occurs then the message will be dropped. - */ - public final boolean sendMessageDelayed(Message msg, long delayMillis) { - return mExec.sendMessageDelayed(msg, delayMillis); - } + @NonNull Lock lock; - /** - * Enqueue a message into the message queue after all pending messages - * before the absolute time (in milliseconds) uptimeMillis. - * The time-base is {@link android.os.SystemClock#uptimeMillis}. - * You will receive it in callback, in the thread attached - * to this handler. - * - * @param uptimeMillis The absolute time at which the message should be - * delivered, using the - * {@link android.os.SystemClock#uptimeMillis} time-base. - * - * @return Returns true if the message was successfully placed in to the - * message queue. Returns false on failure, usually because the - * looper processing the message queue is exiting. Note that a - * result of true does not mean the message will be processed -- if - * the looper is quit before the delivery time of the message - * occurs then the message will be dropped. - */ - public boolean sendMessageAtTime(Message msg, long uptimeMillis) { - return mExec.sendMessageAtTime(msg, uptimeMillis); + public ChainedRef(@NonNull Lock lock, @NonNull Runnable r) { + this.runnable = r; + this.lock = lock; + this.wrapper = new WeakRunnable(new WeakReference<>(r), new WeakReference<>(this)); } - /** - * Enqueue a message at the front of the message queue, to be processed on - * the next iteration of the message loop. You will receive it in - * callback, in the thread attached to this handler. - * This method is only for use in very special circumstances -- it - * can easily starve the message queue, cause ordering problems, or have - * other unexpected side-effects. - * - * @return Returns true if the message was successfully placed in to the - * message queue. Returns false on failure, usually because the - * looper processing the message queue is exiting. - */ - public final boolean sendMessageAtFrontOfQueue(Message msg) { - return mExec.sendMessageAtFrontOfQueue(msg); - } - - /** - * Remove any pending posts of messages with code 'what' that are in the - * message queue. - */ - public final void removeMessages(int what) { - mExec.removeMessages(what); - } - - /** - * Remove any pending posts of messages with code 'what' and whose obj is - * 'object' that are in the message queue. If object is null, - * all messages will be removed. - */ - public final void removeMessages(int what, Object object) { - mExec.removeMessages(what, object); - } - - /** - * Remove any pending posts of callbacks and sent messages whose - * obj is token. If token is null, - * all callbacks and messages will be removed. - */ - public final void removeCallbacksAndMessages(Object token) { - mExec.removeCallbacksAndMessages(token); - } - - /** - * Check if there are any pending posts of messages with code 'what' in - * the message queue. - */ - public final boolean hasMessages(int what) { - return mExec.hasMessages(what); - } - - /** - * Check if there are any pending posts of messages with code 'what' and - * whose obj is 'object' in the message queue. - */ - public final boolean hasMessages(int what, Object object) { - return mExec.hasMessages(what, object); - } - - public final Looper getLooper() { - return mExec.getLooper(); - } - - private WeakRunnable wrapRunnable(@NonNull Runnable r) { - //noinspection ConstantConditions - if (r == null) { - throw new NullPointerException("Runnable can't be null"); - } - final ChainedRef hardRef = new ChainedRef(mLock, r); - mRunnables.insertAfter(hardRef); - return hardRef.wrapper; - } - - private static class ExecHandler extends Handler { - private final WeakReference mCallback; - - ExecHandler() { - mCallback = null; - } - - ExecHandler(WeakReference callback) { - mCallback = callback; - } - - ExecHandler(Looper looper) { - super(looper); - mCallback = null; + public WeakRunnable remove() { + lock.lock(); + try { + if (prev != null) { + prev.next = next; } - - ExecHandler(Looper looper, WeakReference callback) { - super(looper); - mCallback = callback; - } - - @Override - public void handleMessage(@NonNull Message msg) { - if (mCallback == null) { - return; - } - final Handler.Callback callback = mCallback.get(); - if (callback == null) { // Already disposed - return; - } - callback.handleMessage(msg); + if (next != null) { + next.prev = prev; } + prev = null; + next = null; + } finally { + lock.unlock(); + } + return wrapper; } - static class WeakRunnable implements Runnable { - private final WeakReference mDelegate; - private final WeakReference mReference; - - WeakRunnable(WeakReference delegate, WeakReference reference) { - mDelegate = delegate; - mReference = reference; + public void insertAfter(@NonNull ChainedRef candidate) { + lock.lock(); + try { + if (this.next != null) { + this.next.prev = candidate; } - @Override - public void run() { - final Runnable delegate = mDelegate.get(); - final ChainedRef reference = mReference.get(); - if (reference != null) { - reference.remove(); - } - if (delegate != null) { - delegate.run(); - } - } + candidate.next = this.next; + this.next = candidate; + candidate.prev = this; + } finally { + lock.unlock(); + } } - static class ChainedRef { - @Nullable - ChainedRef next; - @Nullable - ChainedRef prev; - @NonNull - final Runnable runnable; - @NonNull - final WeakRunnable wrapper; - - @NonNull - Lock lock; - - public ChainedRef(@NonNull Lock lock, @NonNull Runnable r) { - this.runnable = r; - this.lock = lock; - this.wrapper = new WeakRunnable(new WeakReference<>(r), new WeakReference<>(this)); - } - - public WeakRunnable remove() { - lock.lock(); - try { - if (prev != null) { - prev.next = next; - } - if (next != null) { - next.prev = prev; - } - prev = null; - next = null; - } finally { - lock.unlock(); - } - return wrapper; - } - - public void insertAfter(@NonNull ChainedRef candidate) { - lock.lock(); - try { - if (this.next != null) { - this.next.prev = candidate; - } - - candidate.next = this.next; - this.next = candidate; - candidate.prev = this; - } finally { - lock.unlock(); - } - } - - @Nullable - public WeakRunnable remove(Runnable obj) { - lock.lock(); - try { - ChainedRef curr = this.next; // Skipping head - while (curr != null) { - if (curr.runnable == obj) { // We do comparison exactly how Handler does inside - return curr.remove(); - } - curr = curr.next; - } - } finally { - lock.unlock(); - } - return null; + @Nullable public WeakRunnable remove(Runnable obj) { + lock.lock(); + try { + ChainedRef curr = this.next; // Skipping head + while (curr != null) { + if (curr.runnable == obj) { // We do comparison exactly how Handler does inside + return curr.remove(); + } + curr = curr.next; } + } finally { + lock.unlock(); + } + return null; } + } } \ No newline at end of file diff --git a/Aria/src/main/java/com/arialyy/aria/window/AriaFileChangeActivity.java b/Aria/src/main/java/com/arialyy/aria/window/AriaFileChangeActivity.java index a0da30e5..dbef9a15 100644 --- a/Aria/src/main/java/com/arialyy/aria/window/AriaFileChangeActivity.java +++ b/Aria/src/main/java/com/arialyy/aria/window/AriaFileChangeActivity.java @@ -1,3 +1,18 @@ +/* + * 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.window; import android.os.Bundle; @@ -49,7 +64,4 @@ public class AriaFileChangeActivity extends FragmentActivity { private void loadMore() { } - - - } diff --git a/Aria/src/main/java/com/arialyy/aria/window/FileChangeAdapter.java b/Aria/src/main/java/com/arialyy/aria/window/FileChangeAdapter.java index e4c31183..1e3335a9 100644 --- a/Aria/src/main/java/com/arialyy/aria/window/FileChangeAdapter.java +++ b/Aria/src/main/java/com/arialyy/aria/window/FileChangeAdapter.java @@ -1,3 +1,18 @@ +/* + * 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.window; import android.content.Context; diff --git a/Aria/src/main/java/com/arialyy/aria/window/FileEntity.java b/Aria/src/main/java/com/arialyy/aria/window/FileEntity.java index e51481e4..e0978bf9 100644 --- a/Aria/src/main/java/com/arialyy/aria/window/FileEntity.java +++ b/Aria/src/main/java/com/arialyy/aria/window/FileEntity.java @@ -1,3 +1,18 @@ +/* + * 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.window; import android.graphics.drawable.Drawable; diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e3dcab96..8e18878f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -29,6 +29,8 @@ + + diff --git a/app/src/main/java/com/arialyy/simple/MainActivity.java b/app/src/main/java/com/arialyy/simple/MainActivity.java index d56a452b..f67abcc4 100644 --- a/app/src/main/java/com/arialyy/simple/MainActivity.java +++ b/app/src/main/java/com/arialyy/simple/MainActivity.java @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.arialyy.simple; import android.content.Intent; diff --git a/app/src/main/java/com/arialyy/simple/base/BaseApplication.java b/app/src/main/java/com/arialyy/simple/base/BaseApplication.java index 187716cf..117a34dd 100644 --- a/app/src/main/java/com/arialyy/simple/base/BaseApplication.java +++ b/app/src/main/java/com/arialyy/simple/base/BaseApplication.java @@ -14,7 +14,6 @@ * limitations under the License. */ - package com.arialyy.simple.base; import android.app.Application; diff --git a/app/src/main/java/com/arialyy/simple/base/BaseDialog.java b/app/src/main/java/com/arialyy/simple/base/BaseDialog.java index 2cc995e6..6233dad4 100644 --- a/app/src/main/java/com/arialyy/simple/base/BaseDialog.java +++ b/app/src/main/java/com/arialyy/simple/base/BaseDialog.java @@ -14,7 +14,6 @@ * limitations under the License. */ - package com.arialyy.simple.base; import android.databinding.ViewDataBinding; @@ -24,9 +23,9 @@ import com.arialyy.frame.core.AbsDialogFragment; /** * Created by “AriaLyy@outlook.com” on 2016/11/14. */ -public abstract class BaseDialog extends AbsDialogFragment{ +public abstract class BaseDialog extends AbsDialogFragment { - protected BaseDialog(Object obj){ + protected BaseDialog(Object obj) { super(obj); } diff --git a/app/src/main/java/com/arialyy/simple/base/BaseModule.java b/app/src/main/java/com/arialyy/simple/base/BaseModule.java index 5806c72d..223a9b65 100644 --- a/app/src/main/java/com/arialyy/simple/base/BaseModule.java +++ b/app/src/main/java/com/arialyy/simple/base/BaseModule.java @@ -14,7 +14,6 @@ * limitations under the License. */ - package com.arialyy.simple.base; import android.content.Context; diff --git a/app/src/main/java/com/arialyy/simple/download/DownloadActivity.java b/app/src/main/java/com/arialyy/simple/download/DownloadActivity.java index eec0ce78..04084e06 100644 --- a/app/src/main/java/com/arialyy/simple/download/DownloadActivity.java +++ b/app/src/main/java/com/arialyy/simple/download/DownloadActivity.java @@ -33,6 +33,7 @@ import com.arialyy.simple.base.BaseActivity; import com.arialyy.simple.databinding.ActivityDownloadMeanBinding; import com.arialyy.simple.download.fragment_download.FragmentActivity; import com.arialyy.simple.download.multi_download.MultiTaskActivity; +import com.arialyy.simple.download.service_download.DownloadService; /** * Created by Lyy on 2016/10/13. @@ -84,6 +85,9 @@ public class DownloadActivity extends BaseActivity public void onClick(View view) { switch (view.getId()) { + case R.id.service: + startService(new Intent(this, DownloadService.class)); + break; case R.id.single_task: startActivity(new Intent(this, SingleTaskActivity.class)); break; diff --git a/app/src/main/java/com/arialyy/simple/download/DownloadDialog.java b/app/src/main/java/com/arialyy/simple/download/DownloadDialog.java index 2a1b94fc..c88904b6 100644 --- a/app/src/main/java/com/arialyy/simple/download/DownloadDialog.java +++ b/app/src/main/java/com/arialyy/simple/download/DownloadDialog.java @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.arialyy.simple.download; import android.content.Context; @@ -21,11 +37,11 @@ import com.arialyy.simple.widget.HorizontalProgressBarWithNumber; */ public class DownloadDialog extends AbsDialog { @Bind(R.id.progressBar) HorizontalProgressBarWithNumber mPb; - @Bind(R.id.start) Button mStart; - @Bind(R.id.stop) Button mStop; - @Bind(R.id.cancel) Button mCancel; - @Bind(R.id.size) TextView mSize; - @Bind(R.id.speed) TextView mSpeed; + @Bind(R.id.start) Button mStart; + @Bind(R.id.stop) Button mStop; + @Bind(R.id.cancel) Button mCancel; + @Bind(R.id.size) TextView mSize; + @Bind(R.id.speed) TextView mSpeed; private static final String DOWNLOAD_URL = "http://static.gaoshouyou.com/d/3a/93/573ae1db9493a801c24bf66128b11e39.apk"; @@ -42,7 +58,7 @@ public class DownloadDialog extends AbsDialog { private void init() { if (Aria.download(this).taskExists(DOWNLOAD_URL)) { DownloadTarget target = Aria.download(this).load(DOWNLOAD_URL); - int p = (int) (target.getCurrentProgress() * 100 / target.getFileSize()); + int p = (int) (target.getCurrentProgress() * 100 / target.getFileSize()); mPb.setProgress(p); } Aria.download(this).addSchedulerListener(new MyDialogDownloadCallback()); @@ -107,7 +123,7 @@ public class DownloadDialog extends AbsDialog { @Override public void onTaskRunning(DownloadTask task) { super.onTaskRunning(task); long current = task.getCurrentProgress(); - long len = task.getFileSize(); + long len = task.getFileSize(); if (len == 0) { mPb.setProgress(0); } else { diff --git a/app/src/main/java/com/arialyy/simple/download/DownloadModule.java b/app/src/main/java/com/arialyy/simple/download/DownloadModule.java index a4303708..aa9dab49 100644 --- a/app/src/main/java/com/arialyy/simple/download/DownloadModule.java +++ b/app/src/main/java/com/arialyy/simple/download/DownloadModule.java @@ -44,9 +44,12 @@ public class DownloadModule extends BaseModule { public DownloadModule(Context context) { super(context); - mTestDownloadUrl.add("http://static.gaoshouyou.com/d/e6/f5/4de6329f9cf5dc3a1d1e6bbcca0d003c.apk"); - mTestDownloadUrl.add("http://static.gaoshouyou.com/d/6e/e5/ff6ecaaf45e532e6d07747af82357472.apk"); - mTestDownloadUrl.add("http://static.gaoshouyou.com/d/36/69/2d3699acfa69e9632262442c46516ad8.apk"); + mTestDownloadUrl.add( + "http://static.gaoshouyou.com/d/e6/f5/4de6329f9cf5dc3a1d1e6bbcca0d003c.apk"); + mTestDownloadUrl.add( + "http://static.gaoshouyou.com/d/6e/e5/ff6ecaaf45e532e6d07747af82357472.apk"); + mTestDownloadUrl.add( + "http://static.gaoshouyou.com/d/36/69/2d3699acfa69e9632262442c46516ad8.apk"); } public String getRadomUrl() { @@ -55,7 +58,7 @@ public class DownloadModule extends BaseModule { return mTestDownloadUrl.get(i); } - public DownloadEntity createRandomDownloadEntity(){ + public DownloadEntity createRandomDownloadEntity() { return createDownloadEntity(getRadomUrl()); } diff --git a/app/src/main/java/com/arialyy/simple/download/DownloadPopupWindow.java b/app/src/main/java/com/arialyy/simple/download/DownloadPopupWindow.java index 294d8003..450f3004 100644 --- a/app/src/main/java/com/arialyy/simple/download/DownloadPopupWindow.java +++ b/app/src/main/java/com/arialyy/simple/download/DownloadPopupWindow.java @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.arialyy.simple.download; import android.content.Context; @@ -23,11 +39,11 @@ import com.arialyy.simple.widget.HorizontalProgressBarWithNumber; */ public class DownloadPopupWindow extends AbsPopupWindow { @Bind(R.id.progressBar) HorizontalProgressBarWithNumber mPb; - @Bind(R.id.start) Button mStart; - @Bind(R.id.stop) Button mStop; - @Bind(R.id.cancel) Button mCancel; - @Bind(R.id.size) TextView mSize; - @Bind(R.id.speed) TextView mSpeed; + @Bind(R.id.start) Button mStart; + @Bind(R.id.stop) Button mStop; + @Bind(R.id.cancel) Button mCancel; + @Bind(R.id.size) TextView mSize; + @Bind(R.id.speed) TextView mSpeed; private static final String DOWNLOAD_URL = "http://static.gaoshouyou.com/d/3a/93/573ae1db9493a801c24bf66128b11e39.apk"; @@ -44,7 +60,7 @@ public class DownloadPopupWindow extends AbsPopupWindow { private void initWidget() { if (Aria.download(this).taskExists(DOWNLOAD_URL)) { DownloadTarget target = Aria.download(this).load(DOWNLOAD_URL); - int p = (int) (target.getCurrentProgress() * 100 / target.getFileSize()); + int p = (int) (target.getCurrentProgress() * 100 / target.getFileSize()); mPb.setProgress(p); } Aria.download(this).addSchedulerListener(new MyDialogDownloadCallback()); @@ -109,7 +125,7 @@ public class DownloadPopupWindow extends AbsPopupWindow { @Override public void onTaskRunning(DownloadTask task) { super.onTaskRunning(task); long current = task.getCurrentProgress(); - long len = task.getFileSize(); + long len = task.getFileSize(); if (len == 0) { mPb.setProgress(0); } else { diff --git a/app/src/main/java/com/arialyy/simple/download/SimpleNotification.java b/app/src/main/java/com/arialyy/simple/download/SimpleNotification.java index 7fd48a2a..9adcd304 100644 --- a/app/src/main/java/com/arialyy/simple/download/SimpleNotification.java +++ b/app/src/main/java/com/arialyy/simple/download/SimpleNotification.java @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.arialyy.simple.download; import android.app.NotificationManager; diff --git a/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java b/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java index 1426893f..ff595bbb 100644 --- a/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java +++ b/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java @@ -26,7 +26,6 @@ import android.os.Message; import android.support.v7.widget.Toolbar; import android.view.View; import android.widget.Button; -import android.widget.ImageView; import android.widget.RadioGroup; import android.widget.TextView; import android.widget.Toast; @@ -38,6 +37,7 @@ import com.arialyy.aria.core.download.DownloadTask; import com.arialyy.aria.util.CommonUtil; import com.arialyy.aria.util.Speed; 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.ActivitySingleBinding; @@ -239,6 +239,12 @@ public class SingleTaskActivity extends BaseActivity { } private class MySchedulerListener extends Aria.DownloadSchedulerListener { + + @Override public void onNoSupportBreakPoint(DownloadTask task) { + super.onNoSupportBreakPoint(task); + T.showShort(SingleTaskActivity.this, "该下载链接不支持断点"); + } + @Override public void onTaskStart(DownloadTask task) { mUpdateHandler.obtainMessage(DOWNLOAD_PRE, task.getDownloadEntity().getFileSize()) .sendToTarget(); diff --git a/app/src/main/java/com/arialyy/simple/download/fragment_download/DownloadFragment.java b/app/src/main/java/com/arialyy/simple/download/fragment_download/DownloadFragment.java index 133c884e..661032d1 100644 --- a/app/src/main/java/com/arialyy/simple/download/fragment_download/DownloadFragment.java +++ b/app/src/main/java/com/arialyy/simple/download/fragment_download/DownloadFragment.java @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.arialyy.simple.download.fragment_download; import android.os.Bundle; @@ -34,7 +50,7 @@ public class DownloadFragment extends AbsFragment { @Override protected void init(Bundle savedInstanceState) { if (Aria.download(this).taskExists(DOWNLOAD_URL)) { DownloadTarget target = Aria.download(this).load(DOWNLOAD_URL); - int p = (int) (target.getCurrentProgress() * 100 / target.getFileSize()); + int p = (int) (target.getCurrentProgress() * 100 / target.getFileSize()); mPb.setProgress(p); } DownloadEntity entity = Aria.download(this).getDownloadEntity(DOWNLOAD_URL); @@ -112,7 +128,7 @@ public class DownloadFragment extends AbsFragment { @Override public void onTaskRunning(DownloadTask task) { super.onTaskRunning(task); long current = task.getCurrentProgress(); - long len = task.getFileSize(); + long len = task.getFileSize(); if (len == 0) { mPb.setProgress(0); } else { diff --git a/app/src/main/java/com/arialyy/simple/download/fragment_download/FragmentActivity.java b/app/src/main/java/com/arialyy/simple/download/fragment_download/FragmentActivity.java index 385c5769..9b3c48cb 100644 --- a/app/src/main/java/com/arialyy/simple/download/fragment_download/FragmentActivity.java +++ b/app/src/main/java/com/arialyy/simple/download/fragment_download/FragmentActivity.java @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.arialyy.simple.download.fragment_download; import com.arialyy.simple.R; diff --git a/app/src/main/java/com/arialyy/simple/download/multi_download/DownloadAdapter.java b/app/src/main/java/com/arialyy/simple/download/multi_download/DownloadAdapter.java index 165d2959..430d3008 100644 --- a/app/src/main/java/com/arialyy/simple/download/multi_download/DownloadAdapter.java +++ b/app/src/main/java/com/arialyy/simple/download/multi_download/DownloadAdapter.java @@ -39,8 +39,8 @@ import java.util.concurrent.ConcurrentHashMap; * 下载列表适配器 */ final class DownloadAdapter extends AbsRVAdapter { - private static final String TAG = "DownloadAdapter"; - private Map mPositions = new ConcurrentHashMap<>(); + private static final String TAG = "DownloadAdapter"; + private Map mPositions = new ConcurrentHashMap<>(); DownloadAdapter(Context context, List data) { super(context, data); @@ -192,14 +192,14 @@ final class DownloadAdapter extends AbsRVAdapter { - @Bind(R.id.list) RecyclerView mList; - @Bind(R.id.toolbar) Toolbar mBar; - private FileListAdapter mAdapter; + @Bind(R.id.list) RecyclerView mList; + @Bind(R.id.toolbar) Toolbar mBar; + private FileListAdapter mAdapter; List mData = new ArrayList<>(); @Override protected int setLayoutId() { diff --git a/app/src/main/java/com/arialyy/simple/download/service_download/DownloadNotification.java b/app/src/main/java/com/arialyy/simple/download/service_download/DownloadNotification.java new file mode 100644 index 00000000..4495530f --- /dev/null +++ b/app/src/main/java/com/arialyy/simple/download/service_download/DownloadNotification.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.arialyy.simple.download.service_download; + +import android.app.NotificationManager; +import android.content.Context; +import android.support.v4.app.NotificationCompat; +import com.arialyy.simple.R; + +/** + * Created by Aria.Lao on 2017/1/18. + */ +public class DownloadNotification { + + private NotificationManager mManager; + private Context mContext; + private NotificationCompat.Builder mBuilder; + private static final int mNotifiyId = 0; + + public DownloadNotification(Context context) { + mContext = context; + init(); + } + + private void init() { + mManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); + mBuilder = new NotificationCompat.Builder(mContext); + mBuilder.setContentTitle("Aria Download Test") + .setContentText("进度条") + .setProgress(100, 0, false) + .setSmallIcon(R.mipmap.ic_launcher); + mManager.notify(mNotifiyId, mBuilder.build()); + } + + public void upload(int progress){ + if (mBuilder != null) { + mBuilder.setProgress(100, progress, false); + mManager.notify(mNotifiyId, mBuilder.build()); + } + } +} diff --git a/app/src/main/java/com/arialyy/simple/download/service_download/DownloadService.java b/app/src/main/java/com/arialyy/simple/download/service_download/DownloadService.java new file mode 100644 index 00000000..92cc65f4 --- /dev/null +++ b/app/src/main/java/com/arialyy/simple/download/service_download/DownloadService.java @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.arialyy.simple.download.service_download; + +import android.app.Service; +import android.content.Intent; +import android.os.Environment; +import android.os.IBinder; +import android.support.annotation.Nullable; +import com.arialyy.aria.core.Aria; +import com.arialyy.aria.core.download.DownloadTask; +import com.arialyy.frame.util.show.T; + +/** + * Created by Aria.Lao on 2017/4/5. + * 在服务中使用 Aria进行下载 + */ +public class DownloadService extends Service { + + private static final String DOWNLOAD_URL = + //"http://kotlinlang.org/docs/kotlin-docs.pdf"; + //"https://atom-installer.github.com/v1.13.0/AtomSetup.exe?s=1484074138&ext=.exe"; + //"http://static.gaoshouyou.com/d/21/e8/61218d78d0e8b79df68dbc18dd484c97.apk"; + //不支持断点的链接 + "http://ox.konsung.net:5555/ksdc-web/download/downloadFile/?fileName=ksdc_1.0.2.apk&rRange=0-"; + private DownloadNotification mNotify; + + @Nullable @Override public IBinder onBind(Intent intent) { + return null; + } + + @Override public int onStartCommand(Intent intent, int flags, int startId) { + return super.onStartCommand(intent, flags, startId); + } + + @Override public void onCreate() { + super.onCreate(); + mNotify = new DownloadNotification(getApplicationContext()); + Aria.download(this).addSchedulerListener(new MySchedulerListener()); + Aria.download(this) + .load(DOWNLOAD_URL) + .setDownloadPath(Environment.getExternalStorageDirectory().getPath() + "/service_task.apk") + .start(); + } + + @Override public void onDestroy() { + super.onDestroy(); + Aria.download(this).removeSchedulerListener(); + } + + private class MySchedulerListener extends Aria.DownloadSchedulerListener { + + @Override public void onNoSupportBreakPoint(DownloadTask task) { + super.onNoSupportBreakPoint(task); + T.showShort(getApplicationContext(), "该下载链接不支持断点"); + } + + @Override public void onTaskStart(DownloadTask task) { + T.showShort(getApplicationContext(), task.getDownloadEntity().getFileName() + ",开始下载"); + } + + @Override public void onTaskResume(DownloadTask task) { + super.onTaskResume(task); + } + + @Override public void onTaskStop(DownloadTask task) { + T.showShort(getApplicationContext(), task.getDownloadEntity().getFileName() + ",停止下载"); + } + + @Override public void onTaskCancel(DownloadTask task) { + T.showShort(getApplicationContext(), task.getDownloadEntity().getFileName() + ",取消下载"); + } + + @Override public void onTaskFail(DownloadTask task) { + T.showShort(getApplicationContext(), task.getDownloadEntity().getFileName() + ",下载失败"); + } + + @Override public void onTaskComplete(DownloadTask task) { + T.showShort(getApplicationContext(), task.getDownloadEntity().getFileName() + ",下载完成"); + mNotify.upload(100); + } + + @Override public void onTaskRunning(DownloadTask task) { + long len = task.getFileSize(); + int p = (int) (task.getCurrentProgress() * 100 / len); + mNotify.upload(p); + } + } +} diff --git a/app/src/main/java/com/arialyy/simple/upload/UploadActivity.java b/app/src/main/java/com/arialyy/simple/upload/UploadActivity.java index 9d9809f3..6325df0e 100644 --- a/app/src/main/java/com/arialyy/simple/upload/UploadActivity.java +++ b/app/src/main/java/com/arialyy/simple/upload/UploadActivity.java @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.arialyy.simple.upload; import android.os.Bundle; diff --git a/app/src/main/java/com/arialyy/simple/widget/HorizontalProgressBarWithNumber.java b/app/src/main/java/com/arialyy/simple/widget/HorizontalProgressBarWithNumber.java index 0e8512a0..7c120850 100644 --- a/app/src/main/java/com/arialyy/simple/widget/HorizontalProgressBarWithNumber.java +++ b/app/src/main/java/com/arialyy/simple/widget/HorizontalProgressBarWithNumber.java @@ -14,7 +14,6 @@ * limitations under the License. */ - package com.arialyy.simple.widget; import android.content.Context; @@ -27,53 +26,50 @@ import android.widget.ProgressBar; import com.arialyy.simple.R; public class HorizontalProgressBarWithNumber extends ProgressBar { - private static final int DEFAULT_TEXT_SIZE = 10; - private static final int DEFAULT_TEXT_COLOR = 0XFFFC00D1; - private static final int DEFAULT_COLOR_UNREACHED_COLOR = 0xFFd3d6da; - private static final int DEFAULT_HEIGHT_REACHED_PROGRESS_BAR = 2; - private static final int DEFAULT_HEIGHT_UNREACHED_PROGRESS_BAR = 2; - private static final int DEFAULT_SIZE_TEXT_OFFSET = 10; + private static final int DEFAULT_TEXT_SIZE = 10; + private static final int DEFAULT_TEXT_COLOR = 0XFFFC00D1; + private static final int DEFAULT_COLOR_UNREACHED_COLOR = 0xFFd3d6da; + private static final int DEFAULT_HEIGHT_REACHED_PROGRESS_BAR = 2; + private static final int DEFAULT_HEIGHT_UNREACHED_PROGRESS_BAR = 2; + private static final int DEFAULT_SIZE_TEXT_OFFSET = 10; /** * painter of all drawing things */ - protected Paint mPaint = new Paint(); + protected Paint mPaint = new Paint(); /** * color of progress number */ - protected int mTextColor = DEFAULT_TEXT_COLOR; + protected int mTextColor = DEFAULT_TEXT_COLOR; /** * size of text (sp) */ - protected int mTextSize = sp2px(DEFAULT_TEXT_SIZE); + protected int mTextSize = sp2px(DEFAULT_TEXT_SIZE); /** * offset of draw progress */ - protected int mTextOffset = - dp2px(DEFAULT_SIZE_TEXT_OFFSET); + protected int mTextOffset = dp2px(DEFAULT_SIZE_TEXT_OFFSET); /** * height of reached progress bar */ - protected int mReachedProgressBarHeight = - dp2px(DEFAULT_HEIGHT_REACHED_PROGRESS_BAR); + protected int mReachedProgressBarHeight = dp2px(DEFAULT_HEIGHT_REACHED_PROGRESS_BAR); /** * color of reached bar */ - protected int mReachedBarColor = DEFAULT_TEXT_COLOR; + protected int mReachedBarColor = DEFAULT_TEXT_COLOR; /** * color of unreached bar */ - protected int mUnReachedBarColor = DEFAULT_COLOR_UNREACHED_COLOR; + protected int mUnReachedBarColor = DEFAULT_COLOR_UNREACHED_COLOR; /** * height of unreached progress bar */ - protected int mUnReachedProgressBarHeight = - dp2px(DEFAULT_HEIGHT_UNREACHED_PROGRESS_BAR); + protected int mUnReachedProgressBarHeight = dp2px(DEFAULT_HEIGHT_UNREACHED_PROGRESS_BAR); /** * view width except padding */ protected int mRealWidth; - protected boolean mIfDrawText = true; - protected static final int VISIBLE = 0; + protected boolean mIfDrawText = true; + protected static final int VISIBLE = 0; public HorizontalProgressBarWithNumber(Context context, AttributeSet attrs) { this(context, attrs, 0); @@ -87,14 +83,14 @@ public class HorizontalProgressBarWithNumber extends ProgressBar { } @Override protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - int width = MeasureSpec.getSize(widthMeasureSpec); + int width = MeasureSpec.getSize(widthMeasureSpec); int height = measureHeight(heightMeasureSpec); setMeasuredDimension(width, height); mRealWidth = getMeasuredWidth() - getPaddingRight() - getPaddingLeft(); } private int measureHeight(int measureSpec) { - int result = 0; + int result = 0; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); if (specMode == MeasureSpec.EXACTLY) { @@ -148,12 +144,12 @@ public class HorizontalProgressBarWithNumber extends ProgressBar { @Override protected synchronized void onDraw(Canvas canvas) { canvas.save(); canvas.translate(getPaddingLeft(), getHeight() / 2); - boolean noNeedBg = false; - float radio = getProgress() * 1.0f / getMax(); - float progressPosX = (int) (mRealWidth * radio); - String text = getProgress() + "%"; + boolean noNeedBg = false; + float radio = getProgress() * 1.0f / getMax(); + float progressPosX = (int) (mRealWidth * radio); + String text = getProgress() + "%"; // mPaint.getTextBounds(text, 0, text.length(), mTextBound); - float textWidth = mPaint.measureText(text); + float textWidth = mPaint.measureText(text); float textHeight = (mPaint.descent() + mPaint.ascent()) / 2; if (progressPosX + textWidth > mRealWidth) { progressPosX = mRealWidth - textWidth; diff --git a/app/src/main/res/layout/activity_download_mean.xml b/app/src/main/res/layout/activity_download_mean.xml index 08ccd012..e52848d1 100644 --- a/app/src/main/res/layout/activity_download_mean.xml +++ b/app/src/main/res/layout/activity_download_mean.xml @@ -65,5 +65,14 @@ style="?buttonBarButtonStyle" /> +