From b0818537f2a69e54d8c5f1ed0667ed3b263de155 Mon Sep 17 00:00:00 2001 From: laoyuyu <511455842@qq.com> Date: Fri, 5 Jul 2019 21:20:38 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BB=BB=E5=8A=A1=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=E5=88=A0=E9=99=A4=E5=A4=B1=E8=B4=A5=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20=E4=BC=98=E5=8C=96=E7=BD=91=E7=BB=9C=E8=BF=9E?= =?UTF-8?q?=E6=8E=A5=E7=8A=B6=E6=80=81=E8=8E=B7=E5=8F=96=E7=9A=84=E9=80=BB?= =?UTF-8?q?=E8=BE=91=20=E4=BF=AE=E5=A4=8D=E9=85=8D=E7=BD=AE=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E7=9A=84=E6=9F=90=E4=BA=9B=E9=85=8D=E7=BD=AE=E5=A4=B1?= =?UTF-8?q?=E6=95=88=E7=9A=84=E9=97=AE=E9=A2=98=20=E6=96=B0=E5=A2=9Em3u8?= =?UTF-8?q?=E5=88=87=E7=89=87=E7=8A=B6=E6=80=81=E6=B3=A8=E8=A7=A3`@M3U8.on?= =?UTF-8?q?PeerStart`=EF=BC=8C`@M3U8.onPeerComplete`=EF=BC=8C`@M3U8.onPeer?= =?UTF-8?q?Fail`=20=E6=96=B0=E5=A2=9E=E5=8A=A8=E6=80=81=E6=8C=87=E5=AE=9Am?= =?UTF-8?q?3u8=E5=8D=8F=E8=AE=AE=E8=A7=86=E9=A2=91=E7=9A=84=E4=B8=8B?= =?UTF-8?q?=E8=BD=BD=E5=8A=9F=E8=83=BD=EF=BC=88=E8=BE=B9=E4=B8=8B=E8=BE=B9?= =?UTF-8?q?=E6=92=AD=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/ISSUE_TEMPLATE/Custom.md | 34 +- .../com/arialyy/aria/core/AriaManager.java | 43 +- .../core/command/{group => }/AbsGroupCmd.java | 5 +- .../command/{normal => }/AbsNormalCmd.java | 26 +- .../core/command/{normal => }/AddCmd.java | 4 +- .../command/{normal => }/CancelAllCmd.java | 15 +- .../core/command/{normal => }/CancelCmd.java | 4 +- .../aria/core/command/CommandManager.java | 131 +++++ .../GroupStartCmd.java => DGSubStartCmd.java} | 9 +- .../GroupStopCmd.java => DGSubStopCmd.java} | 8 +- .../command/{group => }/GroupCmdFactory.java | 10 +- .../{normal => }/HighestPriorityCmd.java | 2 +- .../{normal => }/NormalCmdFactory.java | 7 +- .../core/command/{normal => }/ReStartCmd.java | 4 +- .../command/{normal => }/ResumeAllCmd.java | 2 +- .../core/command/{normal => }/StartCmd.java | 9 +- .../core/command/{normal => }/StopAllCmd.java | 2 +- .../core/command/{normal => }/StopCmd.java | 5 +- .../arialyy/aria/core/common/AbsFileer.java | 37 +- .../aria/core/common/AbsThreadTask.java | 48 +- .../aria/core/common/BaseListener.java | 6 +- .../aria/core/common/IThreadState.java | 14 - .../com/arialyy/aria/core/common/IUtil.java | 7 - .../aria/core/common/NormalFileer.java | 12 +- .../arialyy/aria/core/common/ProxyHelper.java | 113 ++-- .../aria/core/common/SubThreadConfig.java | 2 + .../aria/core/common/ThreadStateManager.java | 6 - .../aria/core/common/ftp/FtpTaskConfig.java | 7 +- .../common/ftp/IFtpUploadInterceptor.java | 6 +- .../aria/core/common/http/HttpTaskConfig.java | 7 +- .../aria/core/config/DGroupConfig.java | 4 +- .../aria/core/config/DownloadConfig.java | 4 +- .../aria/core/config/UploadConfig.java | 4 +- .../aria/core/download/AbsDTarget.java | 12 +- .../core/download/DNormalConfigHandler.java | 12 +- .../aria/core/download/DownloadReceiver.java | 35 +- .../aria/core/download/DownloadTask.java | 12 +- .../aria/core/download/M3U8Listener.java | 75 +++ .../core/download/downloader/Downloader.java | 7 + .../download/downloader/FtpThreadTask.java | 2 + .../downloader/HttpFileInfoThread.java | 2 +- .../download/downloader/HttpThreadTask.java | 2 + .../downloader/SimpleDownloadUtil.java | 5 +- .../core/download/group/AbsGroupUtil.java | 13 +- .../download/group/SubDownloadLoader.java | 6 - .../core/download/m3u8/BaseM3U8Loader.java | 2 +- .../download/m3u8/IBandWidthUrlConverter.java | 6 +- .../download/m3u8/ILiveTsUrlConverter.java | 6 +- .../core/download/m3u8/ITsMergeHandler.java | 6 +- .../download/m3u8/IVodTsUrlConverter.java | 6 +- .../aria/core/download/m3u8/M3U8Entity.java | 96 ++++ .../core/download/m3u8/M3U8InfoThread.java | 6 +- .../core/download/m3u8/M3U8LiveLoader.java | 18 +- .../aria/core/download/m3u8/M3U8LiveUtil.java | 4 - .../core/download/m3u8/M3U8TaskConfig.java | 44 +- .../core/download/m3u8/M3U8ThreadTask.java | 8 +- .../core/download/m3u8/M3U8VodDelegate.java | 47 ++ .../core/download/m3u8/M3U8VodLoader.java | 496 ++++++++++++++---- .../aria/core/download/m3u8/M3U8VodUtil.java | 20 +- .../com/arialyy/aria/core/event/Event.java | 30 ++ .../EventMethodInfo.java} | 17 +- .../arialyy/aria/core/event/EventMsgUtil.java | 153 ++++++ .../aria/core/event/PeerIndexEvent.java | 27 + .../arialyy/aria/core/event/SpeedEvent.java | 25 + .../com/arialyy/aria/core/inf/AbsTarget.java | 73 ++- .../com/arialyy/aria/core/inf/AbsTask.java | 24 +- .../aria/core/inf/IHttpFileLenAdapter.java | 6 +- .../java/com/arialyy/aria/core/inf/ITask.java | 6 +- .../core/manager/DTaskWrapperFactory.java | 6 +- .../aria/core/manager/SubTaskManager.java | 18 +- .../aria/core/manager/ThreadTaskManager.java | 15 +- .../arialyy/aria/core/queue/AbsTaskQueue.java | 33 +- .../core/queue/DownloadGroupTaskQueue.java | 2 +- .../aria/core/queue/DownloadTaskQueue.java | 2 +- .../arialyy/aria/core/queue/TaskFactory.java | 3 +- .../aria/core/queue/UploadTaskQueue.java | 2 +- .../aria/core/queue/pool/BaseCachePool.java | 12 +- .../aria/core/queue/pool/BaseExecutePool.java | 17 +- .../core/queue/pool/DownloadExecutePool.java | 2 +- .../core/queue/pool/DownloadSharePool.java | 4 +- .../aria/core/queue/pool/UploadSharePool.java | 4 +- .../aria/core/scheduler/AbsSchedulers.java | 149 ++++-- .../scheduler/DownloadGroupSchedulers.java | 7 +- .../core/scheduler/DownloadSchedulers.java | 9 +- .../core/scheduler/ISchedulerListener.java | 63 +-- .../aria/core/scheduler/ISchedulers.java | 34 +- .../core/scheduler/M3U8PeerTaskListener.java | 36 ++ .../core/scheduler/NormalTaskListener.java | 116 ++++ ...ulerListener.java => SubTaskListener.java} | 59 +-- .../aria/core/scheduler/UploadSchedulers.java | 7 +- .../aria/core/upload/UploadReceiver.java | 19 +- .../core/upload/uploader/FtpThreadTask.java | 3 +- .../core/upload/uploader/HttpThreadTask.java | 2 + .../upload/uploader/SimpleUploadUtil.java | 14 +- .../aria/core/upload/uploader/Uploader.java | 7 + .../java/com/arialyy/aria/orm/DBConfig.java | 4 +- .../java/com/arialyy/aria/orm/SqlHelper.java | 4 +- .../aria/util/BufferedRandomAccessFile.java | 2 +- .../com/arialyy/aria/util/CommonUtil.java | 28 +- .../com/arialyy/aria/util/RecordUtil.java | 17 +- .../com/arialyy/annotations/Download.java | 2 - .../arialyy/annotations/DownloadGroup.java | 3 - .../java/com/arialyy/annotations/M3U8.java | 57 ++ .../com/arialyy/annotations/TaskEnum.java | 48 ++ .../java/com/arialyy/annotations/Upload.java | 2 - .../com/arialyy/compiler/AriaProcessor.java | 6 + .../java/com/arialyy/compiler/CountFiler.java | 129 ----- .../com/arialyy/compiler/ElementHandler.java | 17 +- .../java/com/arialyy/compiler/EntityInfo.java | 44 ++ .../com/arialyy/compiler/EventProxyFiler.java | 127 +++-- .../com/arialyy/compiler/ParamObtainUtil.java | 124 +++-- .../com/arialyy/compiler/ProxyClassParam.java | 3 +- .../com/arialyy/compiler/ProxyConstance.java | 24 - .../java/com/arialyy/compiler/TaskEnum.java | 56 -- .../java/com/arialyy/compiler/ValuesUtil.java | 21 + DEV_LOG.md | 4 +- app/build.gradle | 16 +- app/lyy.keystore | Bin 0 -> 2170 bytes app/src/main/AndroidManifest.xml | 5 +- .../assets/help_code/KotlinHttpDownload.kt | 2 +- .../java/com/arialyy/simple/MainActivity.java | 8 +- .../arialyy/simple/base/BaseApplication.java | 21 +- .../core/download/KotlinDownloadActivity.kt | 9 - .../core/download/SingleTaskActivity.java | 1 + ...tivity.java => M3U8LiveDLoadActivity.java} | 18 +- ...ctivity.java => M3U8VodDLoadActivity.java} | 38 +- .../download/m3u8/VideoPlayerFragment.java | 217 ++++++++ .../multi_download/FileListAdapter.java | 2 +- .../main/res/layout/activity_m3u8_live.xml | 2 +- app/src/main/res/layout/activity_m3u8_vod.xml | 11 +- .../main/res/layout/fragment_video_player.xml | 47 ++ .../main/res/xml/network_security_config.xml | 7 + build.gradle | 2 +- 133 files changed, 2486 insertions(+), 1193 deletions(-) rename Aria/src/main/java/com/arialyy/aria/core/command/{group => }/AbsGroupCmd.java (95%) rename Aria/src/main/java/com/arialyy/aria/core/command/{normal => }/AbsNormalCmd.java (87%) rename Aria/src/main/java/com/arialyy/aria/core/command/{normal => }/AddCmd.java (91%) rename Aria/src/main/java/com/arialyy/aria/core/command/{normal => }/CancelAllCmd.java (86%) rename Aria/src/main/java/com/arialyy/aria/core/command/{normal => }/CancelCmd.java (91%) create mode 100644 Aria/src/main/java/com/arialyy/aria/core/command/CommandManager.java rename Aria/src/main/java/com/arialyy/aria/core/command/{group/GroupStartCmd.java => DGSubStartCmd.java} (75%) rename Aria/src/main/java/com/arialyy/aria/core/command/{group/GroupStopCmd.java => DGSubStopCmd.java} (82%) rename Aria/src/main/java/com/arialyy/aria/core/command/{group => }/GroupCmdFactory.java (86%) rename Aria/src/main/java/com/arialyy/aria/core/command/{normal => }/HighestPriorityCmd.java (97%) rename Aria/src/main/java/com/arialyy/aria/core/command/{normal => }/NormalCmdFactory.java (93%) rename Aria/src/main/java/com/arialyy/aria/core/command/{normal => }/ReStartCmd.java (90%) rename Aria/src/main/java/com/arialyy/aria/core/command/{normal => }/ResumeAllCmd.java (98%) rename Aria/src/main/java/com/arialyy/aria/core/command/{normal => }/StartCmd.java (96%) rename Aria/src/main/java/com/arialyy/aria/core/command/{normal => }/StopAllCmd.java (88%) rename Aria/src/main/java/com/arialyy/aria/core/command/{normal => }/StopCmd.java (90%) create mode 100644 Aria/src/main/java/com/arialyy/aria/core/download/M3U8Listener.java create mode 100644 Aria/src/main/java/com/arialyy/aria/core/event/Event.java rename Aria/src/main/java/com/arialyy/aria/core/{scheduler/IDownloadSchedulerListener.java => event/EventMethodInfo.java} (69%) create mode 100644 Aria/src/main/java/com/arialyy/aria/core/event/EventMsgUtil.java create mode 100644 Aria/src/main/java/com/arialyy/aria/core/event/PeerIndexEvent.java create mode 100644 Aria/src/main/java/com/arialyy/aria/core/event/SpeedEvent.java create mode 100644 Aria/src/main/java/com/arialyy/aria/core/scheduler/M3U8PeerTaskListener.java create mode 100644 Aria/src/main/java/com/arialyy/aria/core/scheduler/NormalTaskListener.java rename Aria/src/main/java/com/arialyy/aria/core/scheduler/{AbsSchedulerListener.java => SubTaskListener.java} (63%) create mode 100644 AriaAnnotations/src/main/java/com/arialyy/annotations/M3U8.java create mode 100644 AriaAnnotations/src/main/java/com/arialyy/annotations/TaskEnum.java delete mode 100644 AriaCompiler/src/main/java/com/arialyy/compiler/CountFiler.java create mode 100644 AriaCompiler/src/main/java/com/arialyy/compiler/EntityInfo.java delete mode 100644 AriaCompiler/src/main/java/com/arialyy/compiler/TaskEnum.java create mode 100644 app/lyy.keystore rename app/src/main/java/com/arialyy/simple/core/download/m3u8/{M3U8LiveDownloadActivity.java => M3U8LiveDLoadActivity.java} (92%) rename app/src/main/java/com/arialyy/simple/core/download/m3u8/{M3U8VodDownloadActivity.java => M3U8VodDLoadActivity.java} (85%) create mode 100644 app/src/main/java/com/arialyy/simple/core/download/m3u8/VideoPlayerFragment.java create mode 100644 app/src/main/res/layout/fragment_video_player.xml create mode 100644 app/src/main/res/xml/network_security_config.xml diff --git a/.github/ISSUE_TEMPLATE/Custom.md b/.github/ISSUE_TEMPLATE/Custom.md index 4e0df831..90ac4ae1 100644 --- a/.github/ISSUE_TEMPLATE/Custom.md +++ b/.github/ISSUE_TEMPLATE/Custom.md @@ -1,17 +1,17 @@ ---- -name: 问题描述 -about: 描述你遇到的问题或bug - ---- - -## Aria版本 - - -## 什么问题 - - -## 如何复现此问题 - - -## 控制台日志 - +--- +name: 问题描述 +about: 请详细描述你遇到的问题 + +--- + +## Aria版本 + + +## 什么问题 + + +## 如何复现此问题 + + +## 控制台日志 + diff --git a/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java b/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java index 02c4e7cf..4b08afca 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java +++ b/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java @@ -24,26 +24,23 @@ import android.content.Context; import android.net.ConnectivityManager; import android.net.Network; import android.net.NetworkCapabilities; -import android.net.NetworkInfo; import android.net.NetworkRequest; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Looper; -import android.support.annotation.RequiresApi; import android.support.v4.app.DialogFragment; import android.support.v4.app.Fragment; import android.widget.PopupWindow; -import com.arialyy.aria.BuildConfig; -import com.arialyy.aria.core.command.ICmd; +import com.arialyy.aria.core.command.CommandManager; import com.arialyy.aria.core.common.QueueMod; import com.arialyy.aria.core.common.RecordHandler; import com.arialyy.aria.core.config.AppConfig; +import com.arialyy.aria.core.config.Configuration; import com.arialyy.aria.core.config.DGroupConfig; import com.arialyy.aria.core.config.DownloadConfig; import com.arialyy.aria.core.config.UploadConfig; import com.arialyy.aria.core.config.XMLReader; -import com.arialyy.aria.core.config.Configuration; import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.download.DownloadGroupEntity; import com.arialyy.aria.core.download.DownloadReceiver; @@ -75,7 +72,7 @@ import org.xml.sax.SAXException; */ @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) public class AriaManager { private static final String TAG = "AriaManager"; - public static final Object LOCK = new Object(); + private static final Object LOCK = new Object(); public static final String DOWNLOAD_TEMP_DIR = "/Aria/temp/download/"; public static final String UPLOAD_TEMP_DIR = "/Aria/temp/upload/"; /** @@ -90,7 +87,6 @@ import org.xml.sax.SAXException; */ private Map> mSubClass = new ConcurrentHashMap<>(); public static Context APP; - private List mCommands = new ArrayList<>(); private DownloadConfig mDConfig; private UploadConfig mUConfig; private AppConfig mAConfig; @@ -110,7 +106,9 @@ import org.xml.sax.SAXException; public static AriaManager getInstance(Context context) { if (INSTANCE == null) { synchronized (LOCK) { - INSTANCE = new AriaManager(context); + if (INSTANCE == null) { + INSTANCE = new AriaManager(context); + } } } return INSTANCE; @@ -182,6 +180,7 @@ import org.xml.sax.SAXException; Thread.setDefaultUncaughtExceptionHandler(new AriaCrashHandler()); } mAConfig.setLogLevel(mAConfig.getLogLevel()); + CommandManager.init(); } /** @@ -291,34 +290,6 @@ import org.xml.sax.SAXException; return mDGConfig; } - /** - * 设置命令 - */ - public AriaManager setCmd(ICmd command) { - mCommands.add(command); - return this; - } - - /** - * 设置一组命令 - */ - public AriaManager setCmds(List commands) { - if (commands != null && commands.size() > 0) { - mCommands.addAll(commands); - } - return this; - } - - /** - * 执行所有设置的命令 - */ - public synchronized void exe() { - for (ICmd command : mCommands) { - command.executeCmd(); - } - mCommands.clear(); - } - /** * 处理下载操作 */ diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/group/AbsGroupCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/AbsGroupCmd.java similarity index 95% rename from Aria/src/main/java/com/arialyy/aria/core/command/group/AbsGroupCmd.java rename to Aria/src/main/java/com/arialyy/aria/core/command/AbsGroupCmd.java index e4fc6f06..be976d12 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/command/group/AbsGroupCmd.java +++ b/Aria/src/main/java/com/arialyy/aria/core/command/AbsGroupCmd.java @@ -13,13 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.arialyy.aria.core.command.group; +package com.arialyy.aria.core.command; -import com.arialyy.aria.core.command.AbsCmd; import com.arialyy.aria.core.download.DGTaskWrapper; import com.arialyy.aria.core.inf.AbsGroupTask; -import com.arialyy.aria.core.inf.AbsTask; import com.arialyy.aria.core.inf.AbsGroupTaskWrapper; +import com.arialyy.aria.core.inf.AbsTask; import com.arialyy.aria.core.queue.DownloadGroupTaskQueue; import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.CommonUtil; diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/normal/AbsNormalCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/AbsNormalCmd.java similarity index 87% rename from Aria/src/main/java/com/arialyy/aria/core/command/normal/AbsNormalCmd.java rename to Aria/src/main/java/com/arialyy/aria/core/command/AbsNormalCmd.java index 7890b3d6..baa18c9f 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/command/normal/AbsNormalCmd.java +++ b/Aria/src/main/java/com/arialyy/aria/core/command/AbsNormalCmd.java @@ -14,17 +14,13 @@ * limitations under the License. */ -package com.arialyy.aria.core.command.normal; +package com.arialyy.aria.core.command; -import com.arialyy.aria.core.command.AbsCmd; -import com.arialyy.aria.core.command.ICmd; import com.arialyy.aria.core.download.DGTaskWrapper; import com.arialyy.aria.core.download.DTaskWrapper; -import com.arialyy.aria.core.inf.AbsEntity; import com.arialyy.aria.core.inf.AbsTask; import com.arialyy.aria.core.inf.AbsTaskWrapper; import com.arialyy.aria.core.inf.IEntity; -import com.arialyy.aria.core.manager.TaskWrapperManager; import com.arialyy.aria.core.queue.DownloadGroupTaskQueue; import com.arialyy.aria.core.queue.DownloadTaskQueue; import com.arialyy.aria.core.queue.UploadTaskQueue; @@ -130,10 +126,10 @@ public abstract class AbsNormalCmd extends AbsCmd { /** * 删除任务 */ - void removeTask(AbsTaskWrapper taskEntity) { - AbsTask tempTask = getTask(taskEntity.getEntity()); + void removeTask(AbsTaskWrapper wrapper) { + AbsTask tempTask = getTask(wrapper.getKey()); if (tempTask == null) { - tempTask = createTask(taskEntity); + tempTask = createTask(wrapper); } mQueue.cancelTask(tempTask); } @@ -143,7 +139,7 @@ public abstract class AbsNormalCmd extends AbsCmd { */ void startTask() { AbsTask task = getTask(); - if (task == null){ + if (task == null) { task = createTask(); } mQueue.startTask(task); @@ -154,7 +150,7 @@ public abstract class AbsNormalCmd extends AbsCmd { */ void resumeTask() { AbsTask task = getTask(); - if (task == null){ + if (task == null) { task = createTask(); } mQueue.resumeTask(task); @@ -183,8 +179,8 @@ public abstract class AbsNormalCmd extends AbsCmd { * * @return 执行任务 */ - AbsTask getTask(AbsEntity entity) { - return mQueue.getTask(entity.getKey()); + AbsTask getTask(String key) { + return mQueue.getTask(key); } /** @@ -199,11 +195,11 @@ public abstract class AbsNormalCmd extends AbsCmd { /** * 创建指定实体的任务 * - * @param taskEntity 特定的任务实体 + * @param wrapper 特定的任务实体 * @return 创建的任务 */ - AbsTask createTask(AbsTaskWrapper taskEntity) { + AbsTask createTask(AbsTaskWrapper wrapper) { - return mQueue.createTask(taskEntity); + return mQueue.createTask(wrapper); } } \ No newline at end of file diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/normal/AddCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/AddCmd.java similarity index 91% rename from Aria/src/main/java/com/arialyy/aria/core/command/normal/AddCmd.java rename to Aria/src/main/java/com/arialyy/aria/core/command/AddCmd.java index be001a88..299ba3f8 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/command/normal/AddCmd.java +++ b/Aria/src/main/java/com/arialyy/aria/core/command/AddCmd.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.arialyy.aria.core.command.normal; +package com.arialyy.aria.core.command; import com.arialyy.aria.core.inf.AbsTask; import com.arialyy.aria.core.inf.AbsTaskWrapper; @@ -25,7 +25,7 @@ import com.arialyy.aria.util.ALog; * Created by lyy on 2016/8/22. * 添加任务的命令 */ -class AddCmd extends AbsNormalCmd { +final class AddCmd extends AbsNormalCmd { AddCmd(T entity, int taskType) { super(entity, taskType); diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/normal/CancelAllCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/CancelAllCmd.java similarity index 86% rename from Aria/src/main/java/com/arialyy/aria/core/command/normal/CancelAllCmd.java rename to Aria/src/main/java/com/arialyy/aria/core/command/CancelAllCmd.java index f173ac17..4c3f092d 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/command/normal/CancelAllCmd.java +++ b/Aria/src/main/java/com/arialyy/aria/core/command/CancelAllCmd.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.arialyy.aria.core.command.normal; +package com.arialyy.aria.core.command; import com.arialyy.aria.core.download.DGTaskWrapper; import com.arialyy.aria.core.download.DTaskWrapper; @@ -35,7 +35,7 @@ import java.util.List; * Created by AriaL on 2017/6/27. * 删除所有任务,并且删除所有回掉 */ -public class CancelAllCmd extends AbsNormalCmd { +final public class CancelAllCmd extends AbsNormalCmd { /** * removeFile {@code true} 删除已经下载完成的任务,不仅删除下载记录,还会删除已经下载完成的文件,{@code false} * 如果文件已经下载完成,只删除下载记录 @@ -64,7 +64,8 @@ public class CancelAllCmd extends AbsNormalCmd { DbEntity.findDatas(DownloadEntity.class, "isGroupChild=?", "false"); if (entities != null && !entities.isEmpty()) { for (DownloadEntity entity : entities) { - remove(TaskWrapperManager.getInstance().getHttpTaskWrapper(DTaskWrapper.class, entity.getKey())); + remove(TaskWrapperManager.getInstance() + .getHttpTaskWrapper(DTaskWrapper.class, entity.getKey())); } } } @@ -78,7 +79,8 @@ public class CancelAllCmd extends AbsNormalCmd { if (entities != null && !entities.isEmpty()) { for (DownloadGroupEntity entity : entities) { remove( - TaskWrapperManager.getInstance().getDGTaskWrapper(DGTaskWrapper.class, entity.getUrls())); + TaskWrapperManager.getInstance() + .getDGTaskWrapper(DGTaskWrapper.class, entity.getUrls())); } } } @@ -91,13 +93,14 @@ public class CancelAllCmd extends AbsNormalCmd { DbEntity.findDatas(UploadEntity.class, "isGroupChild=?", "false"); if (entities != null && !entities.isEmpty()) { for (UploadEntity entity : entities) { - remove(TaskWrapperManager.getInstance().getHttpTaskWrapper(UTaskWrapper.class, entity.getKey())); + remove(TaskWrapperManager.getInstance() + .getHttpTaskWrapper(UTaskWrapper.class, entity.getKey())); } } } private void remove(AbsTaskWrapper te) { - if (te == null){ + if (te == null) { ALog.w(TAG, "取消任务失败,任务为空"); return; } diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/normal/CancelCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/CancelCmd.java similarity index 91% rename from Aria/src/main/java/com/arialyy/aria/core/command/normal/CancelCmd.java rename to Aria/src/main/java/com/arialyy/aria/core/command/CancelCmd.java index 815dc628..2e28b781 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/command/normal/CancelCmd.java +++ b/Aria/src/main/java/com/arialyy/aria/core/command/CancelCmd.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.arialyy.aria.core.command.normal; +package com.arialyy.aria.core.command; import com.arialyy.aria.core.inf.AbsTask; import com.arialyy.aria.core.inf.AbsTaskWrapper; @@ -23,7 +23,7 @@ import com.arialyy.aria.core.inf.AbsTaskWrapper; * Created by lyy on 2016/9/20. * 取消命令 */ -public class CancelCmd extends AbsNormalCmd { +final public class CancelCmd extends AbsNormalCmd { /** * removeFile {@code true} 删除已经下载完成的任务,不仅删除下载记录,还会删除已经下载完成的文件,{@code false} * 如果文件已经下载完成,只删除下载记录 diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/CommandManager.java b/Aria/src/main/java/com/arialyy/aria/core/command/CommandManager.java new file mode 100644 index 00000000..786e0d51 --- /dev/null +++ b/Aria/src/main/java/com/arialyy/aria/core/command/CommandManager.java @@ -0,0 +1,131 @@ +/* + * 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.command; + +import com.arialyy.aria.core.event.Event; +import com.arialyy.aria.core.event.EventMsgUtil; +import com.arialyy.aria.util.CommonUtil; + +/** + * 命令处理器 + */ +public class CommandManager { + + private static CommandManager instance; + + private CommandManager() { + EventMsgUtil.getDefault().register(this); + } + + public static CommandManager init() { + if (instance == null) { + synchronized (CommandManager.class) { + if (instance == null) { + instance = new CommandManager(); + } + } + } + return instance; + } + + @Event + public void add(AddCmd cmd) { + if (CommonUtil.isFastDoubleClick()){ + return; + } + cmd.executeCmd(); + } + + @Event + public void start(StartCmd cmd) { + if (CommonUtil.isFastDoubleClick()){ + return; + } + cmd.executeCmd(); + } + + @Event + public void stop(StopCmd cmd) { + if (CommonUtil.isFastDoubleClick()){ + return; + } + cmd.executeCmd(); + } + + @Event + public void cancel(CancelCmd cmd) { + if (CommonUtil.isFastDoubleClick()){ + return; + } + cmd.executeCmd(); + } + + @Event + public void stopAll(StopAllCmd cmd) { + if (CommonUtil.isFastDoubleClick()){ + return; + } + cmd.executeCmd(); + } + + @Event + public void cancelAll(CancelAllCmd cmd) { + if (CommonUtil.isFastDoubleClick()){ + return; + } + cmd.executeCmd(); + } + + @Event + public void reStart(ReStartCmd cmd) { + if (CommonUtil.isFastDoubleClick()){ + return; + } + cmd.executeCmd(); + } + + @Event + public void highestPriority(HighestPriorityCmd cmd) { + if (CommonUtil.isFastDoubleClick()){ + return; + } + cmd.executeCmd(); + } + + @Event + public void resumeAll(ResumeAllCmd cmd) { + if (CommonUtil.isFastDoubleClick()){ + return; + } + cmd.executeCmd(); + } + + @Event + public void subStart(DGSubStartCmd cmd) { + if (CommonUtil.isFastDoubleClick()){ + return; + } + cmd.executeCmd(); + } + + @Event + public void subStop(DGSubStopCmd cmd) { + if (CommonUtil.isFastDoubleClick()){ + return; + } + cmd.executeCmd(); + } +} diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/group/GroupStartCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/DGSubStartCmd.java similarity index 75% rename from Aria/src/main/java/com/arialyy/aria/core/command/group/GroupStartCmd.java rename to Aria/src/main/java/com/arialyy/aria/core/command/DGSubStartCmd.java index d64b9a0b..4cd0e163 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/command/group/GroupStartCmd.java +++ b/Aria/src/main/java/com/arialyy/aria/core/command/DGSubStartCmd.java @@ -13,15 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.arialyy.aria.core.command.group; +package com.arialyy.aria.core.command; import com.arialyy.aria.core.inf.AbsGroupTaskWrapper; /** - * Created by AriaL on 2017/6/29. 任务组开始命令,该命令负责处理任务组子任务的开始\恢复等工作 + * Created by AriaL on 2017/6/29. + * 任务组开始命令,该命令负责处理任务组子任务的开始\恢复等工作 */ -class GroupStartCmd extends AbsGroupCmd { - GroupStartCmd(T wrapper) { +final class DGSubStartCmd extends AbsGroupCmd { + DGSubStartCmd(T wrapper) { super(wrapper); } diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/group/GroupStopCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/DGSubStopCmd.java similarity index 82% rename from Aria/src/main/java/com/arialyy/aria/core/command/group/GroupStopCmd.java rename to Aria/src/main/java/com/arialyy/aria/core/command/DGSubStopCmd.java index 527e4fc2..78b8b63f 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/command/group/GroupStopCmd.java +++ b/Aria/src/main/java/com/arialyy/aria/core/command/DGSubStopCmd.java @@ -13,16 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.arialyy.aria.core.command.group; +package com.arialyy.aria.core.command; import com.arialyy.aria.core.inf.AbsGroupTaskWrapper; /** * Created by AriaL on 2017/6/29. - * 停止任务组的命令 + * 停止任务组子任务的命令 */ -class GroupStopCmd extends AbsGroupCmd { - GroupStopCmd(T entity) { +final class DGSubStopCmd extends AbsGroupCmd { + DGSubStopCmd(T entity) { super(entity); } diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/group/GroupCmdFactory.java b/Aria/src/main/java/com/arialyy/aria/core/command/GroupCmdFactory.java similarity index 86% rename from Aria/src/main/java/com/arialyy/aria/core/command/group/GroupCmdFactory.java rename to Aria/src/main/java/com/arialyy/aria/core/command/GroupCmdFactory.java index 5fcb0826..db7b1f31 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/command/group/GroupCmdFactory.java +++ b/Aria/src/main/java/com/arialyy/aria/core/command/GroupCmdFactory.java @@ -13,10 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.arialyy.aria.core.command.group; +package com.arialyy.aria.core.command; -import com.arialyy.aria.core.AriaManager; -import com.arialyy.aria.core.download.DGTaskWrapper; import com.arialyy.aria.core.inf.AbsGroupTaskWrapper; /** @@ -40,7 +38,7 @@ public class GroupCmdFactory { public static GroupCmdFactory getInstance() { if (INSTANCE == null) { - synchronized (AriaManager.LOCK) { + synchronized (GroupCmdFactory.class) { INSTANCE = new GroupCmdFactory(); } } @@ -58,10 +56,10 @@ public class GroupCmdFactory { AbsGroupCmd cmd = null; switch (type) { case SUB_TASK_START: - cmd = new GroupStartCmd<>(wrapper); + cmd = new DGSubStartCmd<>(wrapper); break; case SUB_TASK_STOP: - cmd = new GroupStopCmd<>(wrapper); + cmd = new DGSubStopCmd<>(wrapper); break; } if (cmd != null) { diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/normal/HighestPriorityCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/HighestPriorityCmd.java similarity index 97% rename from Aria/src/main/java/com/arialyy/aria/core/command/normal/HighestPriorityCmd.java rename to Aria/src/main/java/com/arialyy/aria/core/command/HighestPriorityCmd.java index c701a1e9..f1f8ee9c 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/command/normal/HighestPriorityCmd.java +++ b/Aria/src/main/java/com/arialyy/aria/core/command/HighestPriorityCmd.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.arialyy.aria.core.command.normal; +package com.arialyy.aria.core.command; import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.download.DownloadTask; diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/normal/NormalCmdFactory.java b/Aria/src/main/java/com/arialyy/aria/core/command/NormalCmdFactory.java similarity index 93% rename from Aria/src/main/java/com/arialyy/aria/core/command/normal/NormalCmdFactory.java rename to Aria/src/main/java/com/arialyy/aria/core/command/NormalCmdFactory.java index aef2579a..767a7fdd 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/command/normal/NormalCmdFactory.java +++ b/Aria/src/main/java/com/arialyy/aria/core/command/NormalCmdFactory.java @@ -14,11 +14,8 @@ * limitations under the License. */ -package com.arialyy.aria.core.command.normal; +package com.arialyy.aria.core.command; -import com.arialyy.aria.core.AriaManager; -import com.arialyy.aria.core.command.AbsCmdFactory; -import com.arialyy.aria.core.command.ICmd; import com.arialyy.aria.core.inf.AbsTaskWrapper; /** @@ -75,7 +72,7 @@ public class NormalCmdFactory extends AbsCmdFactory extends AbsNormalCmd { +final class ReStartCmd extends AbsNormalCmd { ReStartCmd(T entity, int taskType) { super(entity, taskType); diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/normal/ResumeAllCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/ResumeAllCmd.java similarity index 98% rename from Aria/src/main/java/com/arialyy/aria/core/command/normal/ResumeAllCmd.java rename to Aria/src/main/java/com/arialyy/aria/core/command/ResumeAllCmd.java index c3a5cde4..e294effb 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/command/normal/ResumeAllCmd.java +++ b/Aria/src/main/java/com/arialyy/aria/core/command/ResumeAllCmd.java @@ -1,4 +1,4 @@ -package com.arialyy.aria.core.command.normal; +package com.arialyy.aria.core.command; import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.download.DGTaskWrapper; diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/normal/StartCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/StartCmd.java similarity index 96% rename from Aria/src/main/java/com/arialyy/aria/core/command/normal/StartCmd.java rename to Aria/src/main/java/com/arialyy/aria/core/command/StartCmd.java index badbae61..07b9b8e6 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/command/normal/StartCmd.java +++ b/Aria/src/main/java/com/arialyy/aria/core/command/StartCmd.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.arialyy.aria.core.command.normal; +package com.arialyy.aria.core.command; import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.common.QueueMod; @@ -41,7 +41,7 @@ import java.util.List; /** * Created by lyy on 2016/8/22. 开始命令 队列模型{@link QueueMod#NOW}、{@link QueueMod#WAIT} */ -class StartCmd extends AbsNormalCmd { +final class StartCmd extends AbsNormalCmd { StartCmd(T entity, int taskType) { super(entity, taskType); @@ -90,8 +90,7 @@ class StartCmd extends AbsNormalCmd { } } else { //任务没执行并且执行队列中没有该任务,才认为任务没有运行中 - if (!task.isRunning() && !mQueue.taskIsRunning(task.getKey()) && !mQueue.taskExists( - task.getKey())) { + if (!mQueue.taskIsRunning(task.getKey())) { resumeTask(); } else { ALog.w(TAG, String.format("任务【%s】已经在运行", task.getTaskName())); @@ -166,7 +165,7 @@ class StartCmd extends AbsNormalCmd { private void handleTask(List waitList) { for (AbsTaskWrapper te : waitList) { if (te.getEntity() == null) continue; - AbsTask task = getTask(te.getEntity()); + AbsTask task = getTask(te.getKey()); if (task != null) continue; if (te instanceof DTaskWrapper) { if (te.getRequestType() == AbsTaskWrapper.D_FTP diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/normal/StopAllCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/StopAllCmd.java similarity index 88% rename from Aria/src/main/java/com/arialyy/aria/core/command/normal/StopAllCmd.java rename to Aria/src/main/java/com/arialyy/aria/core/command/StopAllCmd.java index 498be815..81966da4 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/command/normal/StopAllCmd.java +++ b/Aria/src/main/java/com/arialyy/aria/core/command/StopAllCmd.java @@ -1,4 +1,4 @@ -package com.arialyy.aria.core.command.normal; +package com.arialyy.aria.core.command; import com.arialyy.aria.core.inf.AbsTaskWrapper; diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/normal/StopCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/StopCmd.java similarity index 90% rename from Aria/src/main/java/com/arialyy/aria/core/command/normal/StopCmd.java rename to Aria/src/main/java/com/arialyy/aria/core/command/StopCmd.java index f8741a74..57c04eb4 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/command/normal/StopCmd.java +++ b/Aria/src/main/java/com/arialyy/aria/core/command/StopCmd.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.arialyy.aria.core.command.normal; +package com.arialyy.aria.core.command; import com.arialyy.aria.core.inf.AbsTask; import com.arialyy.aria.core.inf.AbsTaskWrapper; @@ -25,7 +25,7 @@ import com.arialyy.aria.util.ALog; * Created by lyy on 2016/9/20. * 停止命令 */ -class StopCmd extends AbsNormalCmd { +final class StopCmd extends AbsNormalCmd { StopCmd(T entity, int taskType) { super(entity, taskType); @@ -36,7 +36,6 @@ class StopCmd extends AbsNormalCmd { AbsTask task = getTask(); if (task == null) { if (mTaskWrapper.getEntity().getState() == IEntity.STATE_RUNNING) { - createTask(); stopTask(); } else { ALog.w(TAG, "停止命令执行失败,【调度器中没有该任务】"); diff --git a/Aria/src/main/java/com/arialyy/aria/core/common/AbsFileer.java b/Aria/src/main/java/com/arialyy/aria/core/common/AbsFileer.java index 6abfb470..91495d32 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/common/AbsFileer.java +++ b/Aria/src/main/java/com/arialyy/aria/core/common/AbsFileer.java @@ -49,6 +49,7 @@ public abstract class AbsFileer getConfig() { + public SubThreadConfig getConfig() { return mConfig; } /** * 设置线程是否中断 - * - * @param isInterrupted {@code true} 中断 */ - public void setInterrupted(boolean isInterrupted) { - this.isInterrupted = isInterrupted; + public void destroy() { + this.isDestroy = true; + } + + /** + * 线程执行完成 + */ + protected void onThreadComplete() { + } /** @@ -122,7 +128,7 @@ public abstract class AbsThreadTask 0) { @@ -63,6 +66,11 @@ public abstract class NormalFileer downloadCounter = new HashSet<>(), uploadCounter = new HashSet<>(), - downloadGroupCounter = new HashSet<>(), downloadGroupSubCounter = new HashSet<>(); + public static int PROXY_TYPE_UPLOAD = 0x03; + /** + * m3u8 peer + */ + public static int PROXY_TYPE_M3U8_PEER = 0x04; + /** + * 组合任务子任务类型 + */ + public static int PROXY_TYPE_DOWNLOAD_GROUP_SUB = 0x05; public Map> mProxyCache = new ConcurrentHashMap<>(); public static volatile ProxyHelper INSTANCE = null; - private boolean canLoadClass = false; private ProxyHelper() { - //init(); } public static ProxyHelper getInstance() { if (INSTANCE == null) { - synchronized (AriaManager.LOCK) { + synchronized (ProxyHelper.class) { INSTANCE = new ProxyHelper(); } } return INSTANCE; } - /** - * @since 3.4.6 版本开始,已经在ElementHandler中关闭了ProxyClassCounter对象的生成 - */ - @Deprecated - private void init() { - List classes = CommonUtil.getPkgClassNames(AriaManager.APP, - "com.arialyy.aria.ProxyClassCounter"); - canLoadClass = classes != null - && !classes.isEmpty() - && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; - if (canLoadClass) { - for (String className : classes) { - count(className); - } - } - } - - /** - * 是否能读取到代理计数文件 - * - * @return {@code true} 可以读取,{@code false} 不能读取 - */ - public boolean isCanLoadCountClass() { - return canLoadClass; - } - /** * 检查观察者对象的代理文件类型 * @@ -107,7 +76,8 @@ public class ProxyHelper { } result = new HashSet<>(); try { - if (getClass().getClassLoader().loadClass(className.concat("$$DownloadGroupListenerProxy")) + if (getClass().getClassLoader() + .loadClass(className.concat(TaskEnum.DOWNLOAD_GROUP.proxySuffix)) != null) { result.add(PROXY_TYPE_DOWNLOAD_GROUP); } @@ -115,7 +85,7 @@ public class ProxyHelper { //e.printStackTrace(); } try { - if (getClass().getClassLoader().loadClass(className.concat("$$DownloadListenerProxy")) + if (getClass().getClassLoader().loadClass(className.concat(TaskEnum.DOWNLOAD.proxySuffix)) != null) { result.add(PROXY_TYPE_DOWNLOAD); } @@ -124,7 +94,7 @@ public class ProxyHelper { } try { - if (getClass().getClassLoader().loadClass(className.concat("$$UploadListenerProxy")) + if (getClass().getClassLoader().loadClass(className.concat(TaskEnum.UPLOAD.proxySuffix)) != null) { result.add(PROXY_TYPE_UPLOAD); } @@ -132,47 +102,28 @@ public class ProxyHelper { //e.printStackTrace(); } - if (!result.isEmpty()) { - mProxyCache.put(clazz.getName(), result); + try { + if (getClass().getClassLoader().loadClass(className.concat(TaskEnum.M3U8_PEER.proxySuffix)) + != null) { + result.add(PROXY_TYPE_M3U8_PEER); + } + } catch (ClassNotFoundException e) { + //e.printStackTrace(); } - return result; - } - @Deprecated - private void count(String className) { try { - Class clazz = Class.forName(className); - Method download = clazz.getMethod("getDownloadCounter"); - Method downloadGroup = clazz.getMethod("getDownloadGroupCounter"); - Method downloadGroupSub = clazz.getMethod("getDownloadGroupSubCounter"); - Method upload = clazz.getMethod("getUploadCounter"); - Object object = clazz.newInstance(); - Object dc = download.invoke(object); - if (dc != null) { - downloadCounter.addAll((Set) dc); - } - Object dgc = downloadGroup.invoke(object); - if (dgc != null) { - downloadGroupCounter.addAll((Set) dgc); - } - Object dgsc = downloadGroupSub.invoke(object); - if (dgsc != null) { - downloadGroupSubCounter.addAll((Set) dgsc); - } - Object uc = upload.invoke(object); - if (uc != null) { - uploadCounter.addAll((Set) uc); + if (getClass().getClassLoader() + .loadClass(className.concat(TaskEnum.DOWNLOAD_GROUP_SUB.proxySuffix)) + != null) { + result.add(PROXY_TYPE_DOWNLOAD_GROUP_SUB); } } catch (ClassNotFoundException e) { - e.printStackTrace(); - } catch (InstantiationException e) { - e.printStackTrace(); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } catch (NoSuchMethodException e) { - e.printStackTrace(); - } catch (InvocationTargetException e) { - e.printStackTrace(); + //e.printStackTrace(); + } + + if (!result.isEmpty()) { + mProxyCache.put(clazz.getName(), result); } + return result; } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/common/SubThreadConfig.java b/Aria/src/main/java/com/arialyy/aria/core/common/SubThreadConfig.java index 104bfa69..11cf9e52 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/common/SubThreadConfig.java +++ b/Aria/src/main/java/com/arialyy/aria/core/common/SubThreadConfig.java @@ -36,4 +36,6 @@ public class SubThreadConfig { public Handler stateHandler; // 动态文件 public boolean isOpenDynamicFile; + // m3u8切片索引 + public int peerIndex; } \ No newline at end of file diff --git a/Aria/src/main/java/com/arialyy/aria/core/common/ThreadStateManager.java b/Aria/src/main/java/com/arialyy/aria/core/common/ThreadStateManager.java index 836699bf..5b4965d8 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/common/ThreadStateManager.java +++ b/Aria/src/main/java/com/arialyy/aria/core/common/ThreadStateManager.java @@ -16,7 +16,6 @@ package com.arialyy.aria.core.common; import android.os.Bundle; -import android.os.Handler; import android.os.Looper; import android.os.Message; import com.arialyy.aria.core.inf.IEventListener; @@ -62,15 +61,12 @@ public class ThreadStateManager implements IThreadState { case STATE_STOP: mStopNum++; if (isStop()) { - mListener.onStop(mProgress); quitLooper(); } break; case STATE_CANCEL: mCancelNum++; if (isCancel()) { - ALog.d(TAG, "icCancel"); - mListener.onCancel(); quitLooper(); } break; @@ -133,7 +129,6 @@ public class ThreadStateManager implements IThreadState { /** * 所有子线程是否都已经停止 */ - @Override public boolean isStop() { //ALog.d(TAG, // String.format("isStop; stopNum: %s, cancelNum: %s, failNum: %s, completeNum: %s", mStopNum, @@ -168,7 +163,6 @@ public class ThreadStateManager implements IThreadState { /** * 所有子线程是否都已经取消 */ - @Override public boolean isCancel() { //ALog.d(TAG, String.format("isCancel; stopNum: %s, cancelNum: %s, failNum: %s, completeNum: %s", // mStopNum, diff --git a/Aria/src/main/java/com/arialyy/aria/core/common/ftp/FtpTaskConfig.java b/Aria/src/main/java/com/arialyy/aria/core/common/ftp/FtpTaskConfig.java index 58dfc0b9..b5838ab5 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/common/ftp/FtpTaskConfig.java +++ b/Aria/src/main/java/com/arialyy/aria/core/common/ftp/FtpTaskConfig.java @@ -17,6 +17,7 @@ package com.arialyy.aria.core.common.ftp; import com.arialyy.aria.core.FtpUrlEntity; import com.arialyy.aria.core.inf.ITaskConfig; +import java.lang.ref.WeakReference; import java.net.Proxy; /** @@ -39,7 +40,7 @@ public class FtpTaskConfig implements ITaskConfig { /** * 上传拦截器 */ - private IFtpUploadInterceptor uploadInterceptor; + private WeakReference uploadInterceptor; /** * 上传到服务器文件的新文件名{@link FtpInterceptHandler#getNewFileName()} @@ -55,11 +56,11 @@ public class FtpTaskConfig implements ITaskConfig { } public IFtpUploadInterceptor getUploadInterceptor() { - return uploadInterceptor; + return uploadInterceptor.get(); } public void setUploadInterceptor(IFtpUploadInterceptor uploadInterceptor) { - this.uploadInterceptor = uploadInterceptor; + this.uploadInterceptor = new WeakReference<>(uploadInterceptor); } public FtpUrlEntity getUrlEntity() { diff --git a/Aria/src/main/java/com/arialyy/aria/core/common/ftp/IFtpUploadInterceptor.java b/Aria/src/main/java/com/arialyy/aria/core/common/ftp/IFtpUploadInterceptor.java index e61c070c..0248f22b 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/common/ftp/IFtpUploadInterceptor.java +++ b/Aria/src/main/java/com/arialyy/aria/core/common/ftp/IFtpUploadInterceptor.java @@ -41,7 +41,7 @@ import java.util.List; * * */ -public class IFtpUploadInterceptor { +public interface IFtpUploadInterceptor { /** * 处理拦截事件 @@ -49,7 +49,5 @@ public class IFtpUploadInterceptor { * @param entity 上传信息实体 * @param fileList ftp服务器端remotePath下的文件列表 */ - public FtpInterceptHandler onIntercept(UploadEntity entity, List fileList) { - return null; - } + FtpInterceptHandler onIntercept(UploadEntity entity, List fileList); } diff --git a/Aria/src/main/java/com/arialyy/aria/core/common/http/HttpTaskConfig.java b/Aria/src/main/java/com/arialyy/aria/core/common/http/HttpTaskConfig.java index dc45bbb9..447868f8 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/common/http/HttpTaskConfig.java +++ b/Aria/src/main/java/com/arialyy/aria/core/common/http/HttpTaskConfig.java @@ -19,6 +19,7 @@ package com.arialyy.aria.core.common.http; import com.arialyy.aria.core.common.RequestEnum; import com.arialyy.aria.core.inf.IHttpFileLenAdapter; import com.arialyy.aria.core.inf.ITaskConfig; +import java.lang.ref.WeakReference; import java.net.CookieManager; import java.net.Proxy; import java.util.HashMap; @@ -82,17 +83,17 @@ public class HttpTaskConfig implements ITaskConfig { */ private Map formFields = new HashMap<>(); - private IHttpFileLenAdapter fileLenAdapter; + private WeakReference fileLenAdapter; public IHttpFileLenAdapter getFileLenAdapter() { - return fileLenAdapter; + return fileLenAdapter.get(); } /** * 如果是匿名内部类,完成后需要将adapter设置为空,否则会出现内存泄漏 */ public void setFileLenAdapter(IHttpFileLenAdapter fileLenAdapter) { - this.fileLenAdapter = fileLenAdapter; + this.fileLenAdapter = new WeakReference<>(fileLenAdapter); } public Map getFormFields() { diff --git a/Aria/src/main/java/com/arialyy/aria/core/config/DGroupConfig.java b/Aria/src/main/java/com/arialyy/aria/core/config/DGroupConfig.java index 55dda444..5d63a34b 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/config/DGroupConfig.java +++ b/Aria/src/main/java/com/arialyy/aria/core/config/DGroupConfig.java @@ -15,6 +15,8 @@ */ package com.arialyy.aria.core.config; +import com.arialyy.aria.core.event.EventMsgUtil; +import com.arialyy.aria.core.event.SpeedEvent; import com.arialyy.aria.core.queue.DownloadGroupTaskQueue; import java.io.Serializable; @@ -50,7 +52,7 @@ public class DGroupConfig extends BaseTaskConfig implements Serializable { @Override public DGroupConfig setMaxSpeed(int maxSpeed) { super.setMaxSpeed(maxSpeed); - DownloadGroupTaskQueue.getInstance().setMaxSpeed(maxSpeed); + EventMsgUtil.getDefault().post(new SpeedEvent(maxSpeed)); return this; } diff --git a/Aria/src/main/java/com/arialyy/aria/core/config/DownloadConfig.java b/Aria/src/main/java/com/arialyy/aria/core/config/DownloadConfig.java index 69ff2b69..2a4a300f 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/config/DownloadConfig.java +++ b/Aria/src/main/java/com/arialyy/aria/core/config/DownloadConfig.java @@ -15,6 +15,8 @@ */ package com.arialyy.aria.core.config; +import com.arialyy.aria.core.event.EventMsgUtil; +import com.arialyy.aria.core.event.SpeedEvent; import com.arialyy.aria.core.queue.DownloadTaskQueue; import java.io.Serializable; @@ -47,7 +49,7 @@ public class DownloadConfig extends BaseTaskConfig implements Serializable { @Override public DownloadConfig setMaxSpeed(int maxSpeed) { super.setMaxSpeed(maxSpeed); - DownloadTaskQueue.getInstance().setMaxSpeed(maxSpeed); + EventMsgUtil.getDefault().post(new SpeedEvent(maxSpeed)); return this; } diff --git a/Aria/src/main/java/com/arialyy/aria/core/config/UploadConfig.java b/Aria/src/main/java/com/arialyy/aria/core/config/UploadConfig.java index 1a6c3d01..3c4996c0 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/config/UploadConfig.java +++ b/Aria/src/main/java/com/arialyy/aria/core/config/UploadConfig.java @@ -15,6 +15,8 @@ */ package com.arialyy.aria.core.config; +import com.arialyy.aria.core.event.EventMsgUtil; +import com.arialyy.aria.core.event.SpeedEvent; import com.arialyy.aria.core.queue.UploadTaskQueue; import java.io.Serializable; @@ -28,7 +30,7 @@ public class UploadConfig extends BaseTaskConfig implements Serializable { @Override public UploadConfig setMaxSpeed(int maxSpeed) { super.setMaxSpeed(maxSpeed); - UploadTaskQueue.getInstance().setMaxSpeed(maxSpeed); + EventMsgUtil.getDefault().post(new SpeedEvent(maxSpeed)); return this; } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/AbsDTarget.java b/Aria/src/main/java/com/arialyy/aria/core/download/AbsDTarget.java index 633c6ca1..b578353d 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/AbsDTarget.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/AbsDTarget.java @@ -15,8 +15,8 @@ */ package com.arialyy.aria.core.download; -import com.arialyy.aria.core.AriaManager; -import com.arialyy.aria.core.command.normal.NormalCmdFactory; +import com.arialyy.aria.core.command.NormalCmdFactory; +import com.arialyy.aria.core.event.EventMsgUtil; import com.arialyy.aria.core.inf.AbsTarget; import com.arialyy.aria.util.CommonUtil; @@ -43,11 +43,9 @@ abstract class AbsDTarget extends AbsTarget { */ public void setHighestPriority() { if (checkConfig()) { - AriaManager.getInstance(AriaManager.APP) - .setCmd( - CommonUtil.createNormalCmd(getTaskWrapper(), NormalCmdFactory.TASK_HIGHEST_PRIORITY, - checkTaskType())) - .exe(); + EventMsgUtil.getDefault() + .post(CommonUtil.createNormalCmd(getTaskWrapper(), NormalCmdFactory.TASK_HIGHEST_PRIORITY, + checkTaskType())); } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DNormalConfigHandler.java b/Aria/src/main/java/com/arialyy/aria/core/download/DNormalConfigHandler.java index 02e70d93..0abfd286 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/DNormalConfigHandler.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/DNormalConfigHandler.java @@ -17,8 +17,8 @@ package com.arialyy.aria.core.download; import android.text.TextUtils; import com.arialyy.aria.core.common.RecordHandler; -import com.arialyy.aria.core.inf.ITargetHandler; import com.arialyy.aria.core.inf.IConfigHandler; +import com.arialyy.aria.core.inf.ITargetHandler; import com.arialyy.aria.core.inf.ITaskWrapper; import com.arialyy.aria.core.manager.TaskWrapperManager; import com.arialyy.aria.core.queue.DownloadTaskQueue; @@ -93,8 +93,7 @@ class DNormalConfigHandler implements IConfigHandler } @Override public boolean isRunning() { - DownloadTask task = DownloadTaskQueue.getInstance().getTask(mEntity.getKey()); - return task != null && task.isRunning(); + return DownloadTaskQueue.getInstance().taskIsRunning(mEntity.getKey()); } @Override public boolean checkEntity() { @@ -113,9 +112,10 @@ class DNormalConfigHandler implements IConfigHandler File file = new File(mTempFilePath); DTaskWrapper wrapper = (DTaskWrapper) mTarget.getTaskWrapper(); // 缓存文件夹格式:问文件夹/.文件名_码率 - wrapper.asM3U8() - .setCacheDir(String.format("%s/.%s_%s", file.getParent(), file.getName(), - wrapper.asM3U8().getBandWidth())); + String cacheDir = String.format("%s/.%s_%s", file.getParent(), file.getName(), + wrapper.asM3U8().getBandWidth()); + wrapper.asM3U8().setCacheDir(cacheDir); + mEntity.getM3U8Entity().setCacheDir(cacheDir); if (wrapper.getRequestType() == ITaskWrapper.M3U8_VOD) { if (mEntity.getFileSize() == 0) { ALog.w(TAG, 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 8f5d377d..46a76f93 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 @@ -18,16 +18,16 @@ package com.arialyy.aria.core.download; import android.support.annotation.CheckResult; import android.support.annotation.NonNull; import android.text.TextUtils; -import com.arialyy.annotations.DownloadGroup; +import com.arialyy.annotations.TaskEnum; import com.arialyy.aria.core.AriaManager; +import com.arialyy.aria.core.command.CancelAllCmd; import com.arialyy.aria.core.command.ICmd; -import com.arialyy.aria.core.command.normal.CancelAllCmd; -import com.arialyy.aria.core.command.normal.NormalCmdFactory; +import com.arialyy.aria.core.command.NormalCmdFactory; import com.arialyy.aria.core.common.ProxyHelper; +import com.arialyy.aria.core.event.EventMsgUtil; import com.arialyy.aria.core.inf.AbsEntity; import com.arialyy.aria.core.inf.AbsReceiver; import com.arialyy.aria.core.inf.ReceiverType; -import com.arialyy.aria.core.manager.TaskWrapperManager; import com.arialyy.aria.core.scheduler.DownloadGroupSchedulers; import com.arialyy.aria.core.scheduler.DownloadSchedulers; import com.arialyy.aria.orm.DbEntity; @@ -173,9 +173,13 @@ public class DownloadReceiver extends AbsReceiver { if (set != null && !set.isEmpty()) { for (Integer type : set) { if (type == ProxyHelper.PROXY_TYPE_DOWNLOAD) { - DownloadSchedulers.getInstance().register(obj); + DownloadSchedulers.getInstance().register(obj, TaskEnum.DOWNLOAD); } else if (type == ProxyHelper.PROXY_TYPE_DOWNLOAD_GROUP) { - DownloadGroupSchedulers.getInstance().register(obj); + DownloadGroupSchedulers.getInstance().register(obj, TaskEnum.DOWNLOAD_GROUP); + } else if (type == ProxyHelper.PROXY_TYPE_M3U8_PEER) { + DownloadSchedulers.getInstance().register(obj, TaskEnum.M3U8_PEER); + } else if (type == ProxyHelper.PROXY_TYPE_DOWNLOAD_GROUP_SUB) { + DownloadGroupSchedulers.getInstance().register(obj, TaskEnum.DOWNLOAD_GROUP_SUB); } } } else { @@ -417,11 +421,9 @@ public class DownloadReceiver extends AbsReceiver { * 停止所有正在下载的任务,并清空等待队列。 */ public void stopAllTask() { - AriaManager.getInstance(AriaManager.APP) - .setCmd(NormalCmdFactory.getInstance() - .createCmd(new DTaskWrapper(null), NormalCmdFactory.TASK_STOP_ALL, - ICmd.TASK_TYPE_DOWNLOAD)) - .exe(); + EventMsgUtil.getDefault().post(NormalCmdFactory.getInstance() + .createCmd(new DTaskWrapper(null), NormalCmdFactory.TASK_STOP_ALL, + ICmd.TASK_TYPE_DOWNLOAD)); } /** @@ -430,11 +432,9 @@ public class DownloadReceiver extends AbsReceiver { * 2.如果队列执行队列已经满了,则将所有任务添加到等待队列中 */ public void resumeAllTask() { - AriaManager.getInstance(AriaManager.APP) - .setCmd(NormalCmdFactory.getInstance() - .createCmd(new DTaskWrapper(null), NormalCmdFactory.TASK_RESUME_ALL, - ICmd.TASK_TYPE_DOWNLOAD)) - .exe(); + EventMsgUtil.getDefault().post(NormalCmdFactory.getInstance() + .createCmd(new DTaskWrapper(null), NormalCmdFactory.TASK_RESUME_ALL, + ICmd.TASK_TYPE_DOWNLOAD)); } /** @@ -449,7 +449,8 @@ public class DownloadReceiver extends AbsReceiver { (CancelAllCmd) CommonUtil.createNormalCmd(new DTaskWrapper(null), NormalCmdFactory.TASK_CANCEL_ALL, ICmd.TASK_TYPE_DOWNLOAD); cancelCmd.removeFile = removeFile; - ariaManager.setCmd(cancelCmd).exe(); + EventMsgUtil.getDefault().post(cancelCmd); + Set keys = ariaManager.getReceiver().keySet(); for (String key : keys) { ariaManager.getReceiver().remove(key); diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTask.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTask.java index 47fe8d1e..48429040 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTask.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTask.java @@ -24,6 +24,7 @@ import com.arialyy.aria.core.download.downloader.SimpleDownloadUtil; import com.arialyy.aria.core.download.m3u8.M3U8LiveUtil; import com.arialyy.aria.core.download.m3u8.M3U8VodUtil; import com.arialyy.aria.core.inf.AbsNormalTask; +import com.arialyy.aria.core.inf.AbsTaskWrapper; import com.arialyy.aria.core.inf.IDownloadListener; import com.arialyy.aria.core.inf.ITaskWrapper; import com.arialyy.aria.core.scheduler.ISchedulers; @@ -39,7 +40,12 @@ public class DownloadTask extends AbsNormalTask { mTaskWrapper = taskWrapper; mOutHandler = outHandler; mContext = AriaManager.APP; - mListener = new BaseDListener(this, mOutHandler); + if (taskWrapper.getRequestType() == AbsTaskWrapper.M3U8_VOD + || taskWrapper.getRequestType() == AbsTaskWrapper.M3U8_LIVE) { + mListener = new M3U8Listener(this, mOutHandler); + } else { + mListener = new BaseDListener(this, mOutHandler); + } } /** @@ -90,9 +96,9 @@ public class DownloadTask extends AbsNormalTask { @Override protected synchronized IUtil createUtil() { if (mTaskWrapper.getRequestType() == ITaskWrapper.M3U8_VOD) { - return new M3U8VodUtil(mTaskWrapper, (IDownloadListener) mListener); + return new M3U8VodUtil(mTaskWrapper, (M3U8Listener) mListener); } else if (mTaskWrapper.getRequestType() == ITaskWrapper.M3U8_LIVE) { - return new M3U8LiveUtil(mTaskWrapper, (IDownloadListener) mListener); + return new M3U8LiveUtil(mTaskWrapper, (M3U8Listener) mListener); } else { return new SimpleDownloadUtil(mTaskWrapper, (IDownloadListener) mListener); } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/M3U8Listener.java b/Aria/src/main/java/com/arialyy/aria/core/download/M3U8Listener.java new file mode 100644 index 00000000..6c46eae1 --- /dev/null +++ b/Aria/src/main/java/com/arialyy/aria/core/download/M3U8Listener.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.arialyy.aria.core.download; + +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import com.arialyy.aria.core.inf.IDownloadListener; +import com.arialyy.aria.core.inf.IEntity; +import com.arialyy.aria.core.scheduler.ISchedulers; +import com.arialyy.aria.util.CommonUtil; + +/** + * 下载监听类 + */ +public class M3U8Listener extends BaseDListener implements IDownloadListener { + + M3U8Listener(DownloadTask task, Handler outHandler) { + super(task, outHandler); + } + + @Override + public void onPostPre(long fileSize) { + mEntity.setFileSize(fileSize); + mEntity.setConvertFileSize(CommonUtil.formatFileSize(fileSize)); + saveData(IEntity.STATE_POST_PRE, -1); + sendInState2Target(ISchedulers.POST_PRE); + } + + /** + * 切片开始下载 + */ + public void onPeerStart(String m3u8Url, String peerPath, int peerIndex) { + sendPeerStateToTarget(ISchedulers.M3U8_PEER_START, m3u8Url, peerPath, peerIndex); + } + + /** + * 切片下载完成 + */ + public void onPeerComplete(String m3u8Url, String peerPath, int peerIndex) { + sendPeerStateToTarget(ISchedulers.M3U8_PEER_COMPLETE, m3u8Url, peerPath, peerIndex); + } + + /** + * 切片下载失败 + */ + public void onPeerFail(String m3u8Url, String peerPath, int peerIndex) { + sendPeerStateToTarget(ISchedulers.M3U8_PEER_FAIL, m3u8Url, peerPath, peerIndex); + } + + private void sendPeerStateToTarget(int state, String m3u8Url, String peerPath, int peerIndex) { + Bundle bundle = new Bundle(); + bundle.putString(ISchedulers.DATA_M3U8_URL, m3u8Url); + bundle.putString(ISchedulers.DATA_M3U8_PEER_PATH, peerPath); + bundle.putInt(ISchedulers.DATA_M3U8_PEER_INDEX, peerIndex); + Message msg = outHandler.get().obtainMessage(); + msg.setData(bundle); + msg.what = state; + msg.arg1 = ISchedulers.IS_M3U8_PEER; + msg.sendToTarget(); + } +} \ No newline at end of file diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/Downloader.java b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/Downloader.java index e8144b2a..c015b9b3 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/Downloader.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/Downloader.java @@ -21,6 +21,8 @@ import com.arialyy.aria.core.common.RecordHandler; import com.arialyy.aria.core.common.SubThreadConfig; import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.download.DTaskWrapper; +import com.arialyy.aria.core.event.Event; +import com.arialyy.aria.core.event.SpeedEvent; import com.arialyy.aria.core.inf.AbsTaskWrapper; import com.arialyy.aria.core.inf.IDownloadListener; import com.arialyy.aria.exception.BaseException; @@ -95,6 +97,11 @@ public class Downloader extends NormalFileer { } } + @Event + public void setMaxSpeed(SpeedEvent event) { + setMaxSpeed(event.speed); + } + @Override protected void onPostPre() { super.onPostPre(); ((IDownloadListener) mListener).onPostPre(mEntity.getFileSize()); diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpThreadTask.java b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpThreadTask.java index 9f701b07..ed93b711 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpThreadTask.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpThreadTask.java @@ -111,6 +111,8 @@ class FtpThreadTask extends AbsFtpThreadTask { } catch (IOException e) { e.printStackTrace(); } + + onThreadComplete(); } return this; } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpFileInfoThread.java b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpFileInfoThread.java index 0c410b30..3bd63673 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpFileInfoThread.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpFileInfoThread.java @@ -331,7 +331,7 @@ public class HttpFileInfoThread implements Runnable { } } - private static class FileLenAdapter extends IHttpFileLenAdapter { + private static class FileLenAdapter implements IHttpFileLenAdapter { @Override public long handleFileLen(Map> headers) { List sLength = headers.get("Content-Length"); diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpThreadTask.java b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpThreadTask.java index ae1387eb..d396ba46 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpThreadTask.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpThreadTask.java @@ -141,6 +141,8 @@ final class HttpThreadTask extends AbsThreadTask { } catch (IOException e) { e.printStackTrace(); } + + onThreadComplete(); } return this; } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/SimpleDownloadUtil.java b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/SimpleDownloadUtil.java index 8d85df07..e3d2333f 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/SimpleDownloadUtil.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/SimpleDownloadUtil.java @@ -97,15 +97,12 @@ public class SimpleDownloadUtil implements IUtil { new Thread(createInfoThread()).start(); } - @Override public void setMaxSpeed(int speed) { - mDownloader.setMaxSpeed(speed); - } - private void failDownload(BaseException e, boolean needRetry) { if (isStop || isCancel) { return; } mListener.onFail(needRetry, e); + mDownloader.onDestroy(); } /** diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/group/AbsGroupUtil.java b/Aria/src/main/java/com/arialyy/aria/core/download/group/AbsGroupUtil.java index d817207c..f2310b7c 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/group/AbsGroupUtil.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/group/AbsGroupUtil.java @@ -19,12 +19,11 @@ import android.os.Handler; import android.os.Looper; import com.arialyy.aria.core.common.IUtil; import com.arialyy.aria.core.config.Configuration; -import com.arialyy.aria.core.download.DTaskWrapper; import com.arialyy.aria.core.download.DGTaskWrapper; +import com.arialyy.aria.core.download.DTaskWrapper; import com.arialyy.aria.core.inf.IEntity; import com.arialyy.aria.util.ALog; import java.util.Map; -import java.util.Set; import java.util.WeakHashMap; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; @@ -220,16 +219,6 @@ public abstract class AbsGroupUtil implements IUtil, Runnable { } - @Override public void setMaxSpeed(int speed) { - Set keys = mSubQueue.getExec().keySet(); - for (String key : keys) { - SubDownloadLoader dt = mSubQueue.getExec().get(key); - if (dt != null) { - dt.setMaxSpeed(speed); - } - } - } - synchronized void closeTimer() { if (mTimer != null && !mTimer.isShutdown()) { mTimer.shutdown(); diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/group/SubDownloadLoader.java b/Aria/src/main/java/com/arialyy/aria/core/download/group/SubDownloadLoader.java index ff5b4769..85417f8f 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/group/SubDownloadLoader.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/group/SubDownloadLoader.java @@ -127,10 +127,4 @@ class SubDownloadLoader implements IUtil { ALog.w(TAG, String.format("不识别的类型,requestType:%s", mWrapper.getRequestType())); } } - - @Override public void setMaxSpeed(int speed) { - if (mDownloader != null) { - mDownloader.setMaxSpeed(speed); - } - } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/BaseM3U8Loader.java b/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/BaseM3U8Loader.java index 476f91af..c1a9d76e 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/BaseM3U8Loader.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/BaseM3U8Loader.java @@ -30,7 +30,7 @@ public abstract class BaseM3U8Loader extends AbsFileer tsPath) { - return false; - } + boolean merge(@Nullable M3U8KeyInfo keyInfo, List tsPath); } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/IVodTsUrlConverter.java b/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/IVodTsUrlConverter.java index fcf47142..2ccfc7a6 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/IVodTsUrlConverter.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/IVodTsUrlConverter.java @@ -21,7 +21,7 @@ import java.util.List; * M3U8 点播文件下载,ts url转换器,对于某些服务器,返回的ts地址可以是相对地址,也可能是处理过的 * 对于这种情况,你需要使用url转换器将地址转换为可正常访问的http地址 */ -public class IVodTsUrlConverter { +public interface IVodTsUrlConverter { /** * 处理#EXTINF信息,对于某些服务器,返回的切片信息有可能是相对地址,因此,你需要自行转换为可下载http连接 @@ -30,7 +30,5 @@ public class IVodTsUrlConverter { * @param tsUrls ts文件下载地址列表 * @return 根据切片信息转换后的http连接列表,如果你的切片信息是可以直接下载的http连接,直接返回extInf便可 */ - public List convert(String m3u8Url, List tsUrls) { - return null; - } + List convert(String m3u8Url, List tsUrls); } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8Entity.java b/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8Entity.java index 339c7102..1ab5a94c 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8Entity.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8Entity.java @@ -17,7 +17,16 @@ package com.arialyy.aria.core.download.m3u8; import android.os.Parcel; import android.os.Parcelable; +import android.text.TextUtils; +import com.arialyy.aria.core.common.TaskRecord; +import com.arialyy.aria.core.common.ThreadRecord; import com.arialyy.aria.orm.DbEntity; +import com.arialyy.aria.util.ALog; +import com.arialyy.aria.util.DbDataHelper; +import java.io.File; +import java.io.FilenameFilter; +import java.util.ArrayList; +import java.util.List; /** * M3U8实体信息 @@ -44,10 +53,85 @@ public class M3U8Entity extends DbEntity implements Parcelable { */ private boolean isLive; + /** + * 缓存目录 + */ + private String cacheDir; + public boolean isLive() { return isLive; } + /** + * 获取m3u8切片 + * 如果任务未完成,则返回所有已下载完成的切片; + * 如果任务已完成,如果你设置{@link M3U8Delegate#merge(boolean)}合并分块的请求,返回null;如果没有设置该请求,则返回所有已下载完成的切片 + */ + public List getCompletedPeer() { + if (TextUtils.isEmpty(getCacheDir())) { + ALog.w("M3U8Entity", "任务未下载,获取切片失败"); + return null; + } + List peers = new ArrayList<>(); + TaskRecord taskRecord = DbDataHelper.getTaskRecord(filePath); + File cacheDir = new File(getCacheDir()); + if ((taskRecord == null + || taskRecord.threadRecords == null + || taskRecord.threadRecords.isEmpty()) + && !cacheDir.exists()) { + return null; + } + + // 处理任务完成的情况 + if (taskRecord == null + || taskRecord.threadRecords == null + || taskRecord.threadRecords.isEmpty() + && cacheDir.exists()) { + String[] files = cacheDir.list(new FilenameFilter() { + @Override public boolean accept(File dir, String name) { + return name.endsWith(".ts"); + } + }); + for (String fileName : files) { + + PeerInfo peerInfo = + new PeerInfo(Integer.parseInt(fileName.substring(0, fileName.lastIndexOf(".ts"))), + getCacheDir().concat("/").concat(fileName)); + peers.add(peerInfo); + } + + return peers; + } + + // 任务未完成的情况 + if (taskRecord.threadRecords != null + && !taskRecord.threadRecords.isEmpty() + && cacheDir.exists()) { + + for (ThreadRecord tr : taskRecord.threadRecords) { + if (!tr.isComplete) { + continue; + } + String peerPath = String.format("%s/%s.ts", cacheDir, tr.threadId); + if (new File(peerPath).exists()) { + PeerInfo peerInfo = new PeerInfo(tr.threadId, peerPath); + peers.add(peerInfo); + } + } + return peers; + } + + return null; + } + + public String getCacheDir() { + return cacheDir; + } + + public void setCacheDir(String cacheDir) { + this.cacheDir = cacheDir; + } + public void setLive(boolean live) { isLive = live; } @@ -88,6 +172,7 @@ public class M3U8Entity extends DbEntity implements Parcelable { dest.writeInt(this.peerIndex); dest.writeInt(this.peerNum); dest.writeByte(this.isLive ? (byte) 1 : (byte) 0); + dest.writeString(this.cacheDir); } protected M3U8Entity(Parcel in) { @@ -95,6 +180,7 @@ public class M3U8Entity extends DbEntity implements Parcelable { this.peerIndex = in.readInt(); this.peerNum = in.readInt(); this.isLive = in.readByte() != 0; + this.cacheDir = in.readString(); } public static final Creator CREATOR = new Creator() { @@ -106,4 +192,14 @@ public class M3U8Entity extends DbEntity implements Parcelable { return new M3U8Entity[size]; } }; + + public static class PeerInfo { + public PeerInfo(int peerId, String peerPath) { + this.peerId = peerId; + this.peerPath = peerPath; + } + + public int peerId; + public String peerPath; + } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8InfoThread.java b/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8InfoThread.java index c2731639..c4007657 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8InfoThread.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8InfoThread.java @@ -91,7 +91,7 @@ final class M3U8InfoThread implements Runnable { conn.connect(); handleConnect(conn); } catch (IOException e) { - e.printStackTrace(); + failDownload(e.getMessage(), false); } finally { if (conn != null) { conn.disconnect(); @@ -147,7 +147,7 @@ final class M3U8InfoThread implements Runnable { failDownload(String.format("获取M3U8下载地址列表失败,url: %s", mEntity.getUrl()), false); return; } - if (!isLive && mEntity.getM3U8Entity().getPeerNum() != 0) { + if (!isLive && mEntity.getM3U8Entity().getPeerNum() == 0) { mEntity.getM3U8Entity().setPeerNum(extInf.size()); mEntity.getM3U8Entity().update(); } @@ -257,6 +257,8 @@ final class M3U8InfoThread implements Runnable { failDownload(String.format("码率转换器转换后的url地址无效,转换后的url:%s", bandWidthM3u8Url), false); return; } + } else { + ALog.d(TAG, "没有设置码率转换器"); } mTaskWrapper.asM3U8().setBandWidthUrl(bandWidthM3u8Url); ALog.d(TAG, String.format("新码率url:%s", bandWidthM3u8Url)); diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8LiveLoader.java b/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8LiveLoader.java index b29e3b84..162d5bb2 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8LiveLoader.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8LiveLoader.java @@ -99,10 +99,6 @@ public class M3U8LiveLoader extends BaseM3U8Loader { }).start(); } - @Override protected void setMaxSpeed(int maxSpeed) { - // TODO: 2019-06-06 暂不支持 - } - private void notifyLock() { try { LOCK.lock(); @@ -227,16 +223,14 @@ public class M3U8LiveLoader extends BaseM3U8Loader { @Override public boolean handleMessage(Message msg) { switch (msg.what) { case STATE_STOP: - if (isStop()) { + if (isBreak()) { ALog.d(TAG, "任务停止"); - mListener.onStop(mProgress); quitLooper(); } break; case STATE_CANCEL: - if (isCancel()) { + if (isBreak()) { ALog.d(TAG, "任务取消"); - mListener.onCancel(); quitLooper(); } break; @@ -250,10 +244,6 @@ public class M3U8LiveLoader extends BaseM3U8Loader { return false; } - @Override public boolean isStop() { - return false; - } - @Override public boolean isFail() { return false; } @@ -262,10 +252,6 @@ public class M3U8LiveLoader extends BaseM3U8Loader { return false; } - @Override public boolean isCancel() { - return false; - } - @Override public long getCurrentProgress() { return mProgress; } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8LiveUtil.java b/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8LiveUtil.java index e1bc5f20..84b38c77 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8LiveUtil.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8LiveUtil.java @@ -129,10 +129,6 @@ public class M3U8LiveUtil implements IUtil { } } - @Override public void setMaxSpeed(int speed) { - mLoader.setMaxSpeed(speed); - } - /** * 获取直播文件信息 */ diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8TaskConfig.java b/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8TaskConfig.java index 50352a86..d4780351 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8TaskConfig.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8TaskConfig.java @@ -15,6 +15,7 @@ */ package com.arialyy.aria.core.download.m3u8; +import java.lang.ref.WeakReference; import java.util.List; /** @@ -30,7 +31,7 @@ public class M3U8TaskConfig { /** * #EXTINF 标签信息处理器 */ - private IVodTsUrlConverter vodUrlConverter; + private WeakReference vodUrlConverter; /** * 缓存目录 @@ -45,7 +46,7 @@ public class M3U8TaskConfig { /** * 合并处理器 */ - private ITsMergeHandler mergeHandler; + private WeakReference mergeHandler; /** * 已完成的ts分片数量 @@ -65,7 +66,7 @@ public class M3U8TaskConfig { /** * 码率url转换器 */ - private IBandWidthUrlConverter bandWidthUrlConverter; + private WeakReference bandWidthUrlConverter; /** * 码率地址 @@ -80,7 +81,7 @@ public class M3U8TaskConfig { /** * 直播下载,ts url转换器 */ - private ILiveTsUrlConverter liveTsUrlConverter; + private WeakReference liveTsUrlConverter; /** * 直播的m3u8文件更新间隔 @@ -92,6 +93,19 @@ public class M3U8TaskConfig { */ private int maxTsQueueNum = 4; + /** + * 指定的索引位置 + */ + private int jumpIndex; + + public int getJumpIndex() { + return jumpIndex; + } + + public void setJumpIndex(int jumpIndex) { + this.jumpIndex = jumpIndex; + } + public int getMaxTsQueueNum() { return maxTsQueueNum; } @@ -109,12 +123,11 @@ public class M3U8TaskConfig { } public ILiveTsUrlConverter getLiveTsUrlConverter() { - return liveTsUrlConverter; + return liveTsUrlConverter.get(); } - public void setLiveTsUrlConverter( - ILiveTsUrlConverter liveTsUrlConverter) { - this.liveTsUrlConverter = liveTsUrlConverter; + public void setLiveTsUrlConverter(ILiveTsUrlConverter liveTsUrlConverter) { + this.liveTsUrlConverter = new WeakReference<>(liveTsUrlConverter); } public M3U8KeyInfo getKeyInfo() { @@ -134,12 +147,11 @@ public class M3U8TaskConfig { } public IBandWidthUrlConverter getBandWidthUrlConverter() { - return bandWidthUrlConverter; + return bandWidthUrlConverter.get(); } - public void setBandWidthUrlConverter( - IBandWidthUrlConverter bandWidthUrlConverter) { - this.bandWidthUrlConverter = bandWidthUrlConverter; + public void setBandWidthUrlConverter(IBandWidthUrlConverter bandWidthUrlConverter) { + this.bandWidthUrlConverter = new WeakReference<>(bandWidthUrlConverter); } public int getBandWidth() { @@ -175,19 +187,19 @@ public class M3U8TaskConfig { } public ITsMergeHandler getMergeHandler() { - return mergeHandler; + return mergeHandler.get(); } public void setMergeHandler(ITsMergeHandler mergeHandler) { - this.mergeHandler = mergeHandler; + this.mergeHandler = new WeakReference<>(mergeHandler); } public IVodTsUrlConverter getVodUrlConverter() { - return vodUrlConverter; + return vodUrlConverter.get(); } public void setVodUrlConverter(IVodTsUrlConverter vodUrlConverter) { - this.vodUrlConverter = vodUrlConverter; + this.vodUrlConverter = new WeakReference<>(vodUrlConverter); } public List getUrls() { diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8ThreadTask.java b/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8ThreadTask.java index abeb9804..6b9365d3 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8ThreadTask.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8ThreadTask.java @@ -26,7 +26,6 @@ import com.arialyy.aria.core.download.downloader.ConnectionHelp; import com.arialyy.aria.exception.AriaIOException; import com.arialyy.aria.exception.TaskException; import com.arialyy.aria.util.ALog; -import com.arialyy.aria.util.BufferedRandomAccessFile; import java.io.BufferedInputStream; import java.io.FileOutputStream; import java.io.IOException; @@ -40,7 +39,6 @@ import java.nio.ByteBuffer; import java.nio.channels.Channels; import java.nio.channels.FileChannel; import java.nio.channels.ReadableByteChannel; -import java.util.List; import java.util.Map; import java.util.Set; @@ -48,7 +46,7 @@ import java.util.Set; * Created by lyy on 2017/1/18. 下载线程 */ final class M3U8ThreadTask extends AbsThreadTask { - private final String TAG = "HttpThreadTask"; + private final String TAG = "M3U8ThreadTask"; M3U8ThreadTask(SubThreadConfig config) { super(config); @@ -75,9 +73,6 @@ final class M3U8ThreadTask extends AbsThreadTask { conn.setChunkedStreamingMode(0); } conn.connect(); - //Map> header = conn.getHeaderFields(); - //int code = conn.getResponseCode(); - //String msg = conn.getResponseMessage(); // 传递参数 if (taskDelegate.getRequestEnum() == RequestEnum.POST) { Map params = taskDelegate.getParams(); @@ -125,6 +120,7 @@ final class M3U8ThreadTask extends AbsThreadTask { } catch (IOException e) { e.printStackTrace(); } + onThreadComplete(); } return this; } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8VodDelegate.java b/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8VodDelegate.java index 8c68c44c..9e9ae8c2 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8VodDelegate.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8VodDelegate.java @@ -17,8 +17,11 @@ package com.arialyy.aria.core.download.m3u8; import com.arialyy.aria.core.common.BaseDelegate; import com.arialyy.aria.core.download.DTaskWrapper; +import com.arialyy.aria.core.event.EventMsgUtil; +import com.arialyy.aria.core.event.PeerIndexEvent; import com.arialyy.aria.core.inf.AbsTarget; import com.arialyy.aria.core.inf.AbsTaskWrapper; +import com.arialyy.aria.core.queue.DownloadTaskQueue; import com.arialyy.aria.util.ALog; /** @@ -60,4 +63,48 @@ public class M3U8VodDelegate extends BaseDelegate mFlagQueue; - private VodStateManager mManager; + private ArrayBlockingQueue mFlagQueue; + private ArrayBlockingQueue mJumpQueue; private ReentrantLock LOCK = new ReentrantLock(); - private Condition mCondition = LOCK.newCondition(); + private ReentrantLock EVENT_LOCK = new ReentrantLock(); + private ReentrantLock JUMP_LOCK = new ReentrantLock(); + private Condition mWaitCondition = LOCK.newCondition(); + private Condition mEventQueueCondition = EVENT_LOCK.newCondition(); + private Condition mJumpCondition = JUMP_LOCK.newCondition(); + private SparseArray mBeforePeer = new SparseArray<>(); + private SparseArray mAfterPeer = new SparseArray<>(); + private VodStateManager mManager; + private PeerIndexEvent mCurrentEvent; + private String mCacheDir; + private int aIndex = 0, bIndex = 0; + private int mCurrentFlagSize; + private boolean isJump = false, isDestroy = false; + private int mCompleteNum = 0; + private ExecutorService mJumpThreadPool; + private Thread jumpThread = null; - M3U8VodLoader(IEventListener listener, DTaskWrapper wrapper) { + M3U8VodLoader(M3U8Listener listener, DTaskWrapper wrapper) { super(listener, wrapper); mFlagQueue = new ArrayBlockingQueue<>(wrapper.asM3U8().getMaxTsQueueNum()); + EXEC_MAX_NUM = wrapper.asM3U8().getMaxTsQueueNum(); + mJumpQueue = new ArrayBlockingQueue<>(10); + EventMsgUtil.getDefault().register(this); } @Override protected IThreadState getStateManager(Looper looper) { @@ -64,55 +90,299 @@ public class M3U8VodLoader extends BaseM3U8Loader { return mManager; } - @Override protected void handleTask() { + @Override public void onDestroy() { + super.onDestroy(); + isDestroy = true; + EventMsgUtil.getDefault().unRegister(this); + if (mJumpThreadPool != null && !mJumpThreadPool.isShutdown()) { + mJumpThreadPool.shutdown(); + } + } + + @Override protected void onPostPre() { + super.onPostPre(); + initData(); + } + + @Override public boolean isBreak() { + return super.isBreak() || isDestroy; + } - new Thread(new Runnable() { + @Override protected void handleTask() { + Thread th = new Thread(new Runnable() { @Override public void run() { - int index = 0; - String cacheDir = getCacheDir(); while (!isBreak()) { + try { + JUMP_LOCK.lock(); + if (isJump) { + mJumpCondition.await(5, TimeUnit.SECONDS); + isJump = false; + } + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + JUMP_LOCK.unlock(); + } + try { LOCK.lock(); - while (mFlagQueue.size() < EXEC_MAX_NUM) { - if (index == mRecord.threadRecords.size()) { + while (mFlagQueue.size() < EXEC_MAX_NUM && !isBreak()) { + if (mCompleteNum == mRecord.threadRecords.size()) { break; } - ThreadRecord tr = mRecord.threadRecords.get(index); - index++; - if (tr.isComplete) { - continue; - } - M3U8ThreadTask task = createThreadTask(cacheDir, tr); - getTaskList().put(tr.threadId, task); - mEntity.getM3U8Entity().setPeerIndex(index); - mFlagQueue.offer(startThreadTask(task, index)); + ThreadRecord tr = getThreadRecord(); + if (tr == null || tr.isComplete) { + ALog.d(TAG, "记录为空或记录已完成"); + break; + } + addTaskToQueue(tr); } if (mFlagQueue.size() > 0) { - mCondition.await(); + mWaitCondition.await(); } - } catch (InterruptedException e) { + } catch (Exception e) { e.printStackTrace(); } finally { LOCK.unlock(); } } } - }).start(); + }); + th.start(); } - @Override protected void setMaxSpeed(int maxSpeed) { - // TODO: 2019-06-05 暂不支持 + /** + * 获取线程记录 + */ + private ThreadRecord getThreadRecord() { + ThreadRecord tr = null; + try { + // 优先下载peer指针之后的数据 + if (bIndex == 0 && aIndex < mAfterPeer.size()) { + //ALog.d(TAG, String.format("afterArray size:%s, index:%s", mAfterPeer.size(), aIndex)); + tr = mAfterPeer.valueAt(aIndex); + aIndex++; + } + + // 如果指针之后的数组没有切片了,则重新初始化指针位置,并获取指针之前的数组获取切片进行下载 + if (mBeforePeer.size() > 0 && (tr == null || bIndex != 0) && bIndex < mBeforePeer.size()) { + tr = mBeforePeer.valueAt(bIndex); + bIndex++; + } + } catch (Exception e) { + e.printStackTrace(); + } + return tr; } - private void notifyLock() { + /** + * 启动线程任务 + */ + private void addTaskToQueue(ThreadRecord tr) throws InterruptedException { + M3U8ThreadTask task = createThreadTask(mCacheDir, tr, tr.threadId); + getTaskList().put(tr.threadId, task); + mEntity.getM3U8Entity().setPeerIndex(tr.threadId); + TempFlag flag = startThreadTask(task, tr.threadId); + if (flag != null) { + mFlagQueue.put(flag); + } + } + + /** + * 初始化数据 + */ + private void initData() { + mCacheDir = getCacheDir(); + if (mTaskWrapper.asM3U8().getJumpIndex() != 0) { + mCurrentEvent = new PeerIndexEvent(mTaskWrapper.asM3U8().getJumpIndex()); + resumeTask(); + return; + } + // 设置需要下载的切片 + mCompleteNum = 0; + for (ThreadRecord tr : mRecord.threadRecords) { + if (!tr.isComplete) { + mAfterPeer.put(tr.threadId, tr); + } else { + mCompleteNum++; + } + } + mManager.updateStateCount(); + } + + /** + * 每隔几秒钟检查jump队列,取最新的事件处理 + */ + private synchronized void startJumpThread() { + jumpThread = new Thread(new Runnable() { + @Override public void run() { + try { + PeerIndexEvent event; + while (!isBreak()) { + try { + EVENT_LOCK.lock(); + PeerIndexEvent temp = null; + // 取最新的事件 + while ((event = mJumpQueue.poll(1, TimeUnit.SECONDS)) != null) { + temp = event; + } + + if (temp != null) { + handleJump(temp); + } + mEventQueueCondition.await(); + } finally { + EVENT_LOCK.unlock(); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + jumpThread.start(); + } + + /** + * 处理跳转 + */ + private void handleJump(PeerIndexEvent event) { + if (isBreak()) { + ALog.e(TAG, "任务已停止,处理跳转失败"); + return; + } + mCurrentEvent = event; + if (mRecord == null || mRecord.threadRecords == null) { + ALog.e(TAG, "跳到指定位置失败,记录为空"); + return; + } + if (event.peerIndex >= mRecord.threadRecords.size()) { + ALog.e(TAG, + String.format("切片索引设置错误,切片最大索引为:%s,当前设置的索引为:%s", mRecord.threadRecords.size(), + event.peerIndex)); + return; + } + ALog.i(TAG, String.format("将优先下载索引【%s】之后的切片", event.peerIndex)); + + isJump = true; + notifyWaitLock(false); + mCurrentFlagSize = mFlagQueue.size(); + // 停止所有正在执行的线程任务 + try { + TempFlag flag; + while ((flag = mFlagQueue.poll()) != null) { + flag.threadTask.stop(); + } + } catch (Exception e) { + e.printStackTrace(); + } + ALog.d(TAG, "完成停止队列中的切片任务"); + } + + /** + * 下载指定索引后面的切片 + * 如果指定的切片索引大于切片总数,则此操作无效 + * 如果指定的切片索引小于当前正在下载的切片索引,并且指定索引和当前索引区间内有未下载的切片,则优先下载该区间的切片;否则此操作无效 + * 如果指定索引后的切片已经全部下载完成,但是索引前有未下载的切片,间会自动下载未下载的切片 + */ + @Event + public synchronized void jumpPeer(PeerIndexEvent event) { + if (isBreak()) { + ALog.e(TAG, "任务已停止,发送跳转事件失败"); + return; + } + if (jumpThread == null) { + mJumpThreadPool = Executors.newSingleThreadExecutor(); + startJumpThread(); + } + mJumpQueue.offer(event); + mJumpThreadPool.submit(new Runnable() { + @Override public void run() { + try { + Thread.sleep(1000); + notifyJumpQueue(); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + } + + private void notifyJumpQueue() { + try { + EVENT_LOCK.lock(); + mEventQueueCondition.signalAll(); + } catch (Exception e) { + e.printStackTrace(); + } finally { + EVENT_LOCK.unlock(); + } + } + + /** + * 重指定位置恢复任务 + */ + private synchronized void resumeTask() { + if (isBreak()) { + ALog.e(TAG, "任务已停止,恢复任务失败"); + return; + } + if (mJumpQueue.size() > 0) { + ALog.d(TAG, "有新定位,取消上一次操作"); + notifyJumpQueue(); + return; + } + ALog.d(TAG, "恢复切片任务"); + // 重新初始化需要下载的分片 + mBeforePeer.clear(); + mAfterPeer.clear(); + mFlagQueue.clear(); + aIndex = 0; + bIndex = 0; + mCompleteNum = 0; + for (ThreadRecord tr : mRecord.threadRecords) { + if (tr.isComplete) { + mCompleteNum++; + continue; + } + if (tr.threadId < mCurrentEvent.peerIndex) { + mBeforePeer.put(tr.threadId, tr); + } else { + mAfterPeer.put(tr.threadId, tr); + } + } + + ALog.i(TAG, + String.format("beforeSize = %s, afterSize = %s, mCompleteNum = %s", mBeforePeer.size(), + mAfterPeer.size(), mCompleteNum)); + ALog.i(TAG, String.format("完成处理数据的操作,将优先下载【%s】之后的切片", mCurrentEvent.peerIndex)); + mManager.updateStateCount(); + + try { + JUMP_LOCK.lock(); + mJumpCondition.signalAll(); + } finally { + JUMP_LOCK.unlock(); + } + } + + private M3U8Listener getListener() { + return (M3U8Listener) mListener; + } + + private void notifyWaitLock(boolean isComplete) { try { LOCK.lock(); - long id = mFlagQueue.take(); - ALog.d(TAG, String.format("线程【%s】完成", id)); - mCondition.signalAll(); - } catch (InterruptedException e) { + if (isComplete) { + TempFlag flag = mFlagQueue.poll(1, TimeUnit.SECONDS); + if (flag != null) { + ALog.d(TAG, String.format("切片【%s】完成", flag.threadId)); + } + } + mWaitCondition.signalAll(); + } catch (Exception e) { e.printStackTrace(); } finally { LOCK.unlock(); @@ -124,15 +394,24 @@ public class M3U8VodLoader extends BaseM3U8Loader { * * @return 线程唯一id标志 */ - private long startThreadTask(M3U8ThreadTask task, int peerIndex) { + private TempFlag startThreadTask(M3U8ThreadTask task, int peerIndex) { + if (isBreak()) { + ALog.w(TAG, "任务已停止,启动线程任务失败"); + return null; + } ThreadTaskManager.getInstance().startThread(mTaskWrapper.getKey(), task); - return peerIndex; + getListener().onPeerStart(mTaskWrapper.getKey(), task.getConfig().tempFile.getPath(), + peerIndex); + TempFlag flag = new TempFlag(); + flag.threadTask = task; + flag.threadId = peerIndex; + return flag; } /** * 配置config */ - private M3U8ThreadTask createThreadTask(String cacheDir, ThreadRecord record) { + private M3U8ThreadTask createThreadTask(String cacheDir, ThreadRecord record, int index) { SubThreadConfig config = new SubThreadConfig<>(); config.url = record.tsUrl; config.tempFile = new File(getTsFilePath(cacheDir, record.threadId)); @@ -141,6 +420,7 @@ public class M3U8VodLoader extends BaseM3U8Loader { config.taskWrapper = mTaskWrapper; config.record = record; config.stateHandler = mStateHandler; + config.peerIndex = index; if (!config.tempFile.exists()) { CommonUtil.createFile(config.tempFile.getPath()); } @@ -156,29 +436,34 @@ public class M3U8VodLoader extends BaseM3U8Loader { /** * 任务状态回调 */ - private IEventListener mListener; - private int mStartThreadNum; // 启动的线程总数 - private int mCancelNum = 0; // 已经取消的线程的数 - private int mStopNum = 0; // 已经停止的线程数 - private int mFailNum = 0; // 失败的线程数 - private int mCompleteNum = 0; // 完成的线程数 - private long mProgress; //当前总进度 - private TaskRecord mTaskRecord; // 任务记录 - private Looper mLooper; + private IEventListener listener; + private int startThreadNum; // 启动的线程总数 + private int cancelNum = 0; // 已经取消的线程的数 + private int stopNum = 0; // 已经停止的线程数 + private int failNum = 0; // 失败的线程数 + private long progress; //当前总进度 + private TaskRecord taskRecord; // 任务记录 + private Looper looper; /** * @param taskRecord 任务记录 * @param listener 任务事件 */ VodStateManager(Looper looper, TaskRecord taskRecord, IEventListener listener) { - mLooper = looper; - mTaskRecord = taskRecord; + this.looper = looper; + this.taskRecord = taskRecord; for (ThreadRecord record : taskRecord.threadRecords) { if (!record.isComplete) { - mStartThreadNum++; + startThreadNum++; } } - mListener = listener; + this.listener = listener; + } + + private void updateStateCount() { + cancelNum = 0; + stopNum = 0; + failNum = 0; } /** @@ -186,65 +471,104 @@ public class M3U8VodLoader extends BaseM3U8Loader { */ private void quitLooper() { ALog.d(TAG, "quitLooper"); - mLooper.quit(); + looper.quit(); } @Override public boolean handleMessage(Message msg) { + int peerIndex = msg.getData().getInt(ISchedulers.DATA_M3U8_PEER_INDEX); switch (msg.what) { case STATE_STOP: - mStopNum++; - ThreadTaskManager.getInstance().removeSingleTaskThread(mTaskWrapper.getKey(), - (AbsThreadTask) msg.obj); - if (isStop()) { + stopNum++; + removeSignThread((AbsThreadTask) msg.obj); + // 处理跳转位置后,恢复任务 + if (isJump && (stopNum == mCurrentFlagSize || mCurrentFlagSize == 0) && !isBreak()) { + resumeTask(); + return true; + } + + if (isBreak()) { ALog.d(TAG, String.format("vod任务【%s】停止", mTempFile.getName())); - mListener.onStop(mProgress); quitLooper(); } break; case STATE_CANCEL: - mCancelNum++; - ThreadTaskManager.getInstance().removeSingleTaskThread(mTaskWrapper.getKey(), - (AbsThreadTask) msg.obj); - if (isCancel()) { + cancelNum++; + removeSignThread((AbsThreadTask) msg.obj); + + if (isBreak()) { ALog.d(TAG, String.format("vod任务【%s】取消", mTempFile.getName())); - mListener.onCancel(); quitLooper(); } break; case STATE_FAIL: - mFailNum++; + failNum++; + for (ThreadRecord tr : mRecord.threadRecords) { + if (tr.threadId == peerIndex) { + mBeforePeer.put(peerIndex, tr); + break; + } + } + + getListener().onPeerFail(mTaskWrapper.getKey(), + msg.getData().getString(ISchedulers.DATA_M3U8_PEER_PATH), peerIndex); if (isFail()) { ALog.d(TAG, String.format("vod任务【%s】失败", mTempFile.getName())); Bundle b = msg.getData(); - mListener.onFail(b.getBoolean(KEY_RETRY, true), + listener.onFail(b.getBoolean(KEY_RETRY, true), (BaseException) b.getSerializable(KEY_ERROR_INFO)); quitLooper(); } break; case STATE_COMPLETE: + if (isBreak()) { + quitLooper(); + } mCompleteNum++; - ThreadTaskManager.getInstance().removeSingleTaskThread(mTaskWrapper.getKey(), - (AbsThreadTask) msg.obj); + // 正在切换位置时,切片完成,队列大小减小 + if (isJump) { + mCurrentFlagSize--; + if (mCurrentFlagSize < 0) { + mCurrentFlagSize = 0; + } + } + + removeSignThread((AbsThreadTask) msg.obj); + getListener().onPeerComplete(mTaskWrapper.getKey(), + msg.getData().getString(ISchedulers.DATA_M3U8_PEER_PATH), peerIndex); handlerPercent(); - notifyLock(); + if (!isJump) { + notifyWaitLock(true); + } if (isComplete()) { + ALog.d(TAG, String.format( + "startThreadNum = %s, stopNum = %s, cancelNum = %s, failNum = %s, completeNum = %s, flagQueueSize = %s", + startThreadNum, stopNum, cancelNum, failNum, mCompleteNum, mFlagQueue.size())); + ALog.d(TAG, String.format("vod任务【%s】完成", mTempFile.getName())); if (mTaskWrapper.asM3U8().isMergeFile()) { if (mergeFile()) { - mListener.onComplete(); + listener.onComplete(); } else { - mListener.onFail(false, null); + listener.onFail(false, null); } } else { - mListener.onComplete(); + listener.onComplete(); } quitLooper(); } break; case STATE_RUNNING: - mProgress += (long) msg.obj; + progress += (long) msg.obj; break; } - return false; + return true; + } + + private void removeSignThread(AbsThreadTask threadTask) { + int index = getTaskList().indexOfValue(threadTask); + if (index != -1) { + getTaskList().removeAt(index); + } + ThreadTaskManager.getInstance().removeSingleTaskThread(mTaskWrapper.getKey(), threadTask); } /** @@ -254,40 +578,29 @@ public class M3U8VodLoader extends BaseM3U8Loader { int completeNum = mTaskWrapper.asM3U8().getCompleteNum(); completeNum++; mTaskWrapper.asM3U8().setCompleteNum(completeNum); - int percent = completeNum * 100 / mTaskRecord.threadRecords.size(); + int percent = completeNum * 100 / taskRecord.threadRecords.size(); mEntity.setPercent(percent); mEntity.update(); } - @Override public boolean isStop() { - printInfo("isStop"); - return mStopNum == mFlagQueue.size(); - } - @Override public boolean isFail() { printInfo("isFail"); - return mFailNum == mFlagQueue.size(); + return failNum != 0 && failNum == mFlagQueue.size() && !isJump; } @Override public boolean isComplete() { - printInfo("isComplete"); - return mStartThreadNum == mCompleteNum; - } - - @Override public boolean isCancel() { - printInfo("isCancel"); - return mCancelNum == mFlagQueue.size(); + return mCompleteNum == taskRecord.threadRecords.size() && !isJump; } @Override public long getCurrentProgress() { - return mProgress; + return progress; } private void printInfo(String tag) { if (false) { ALog.d(tag, String.format( - "startThreadNum = %s, stopNum = %s, cancelNum = %s, failNum = %s, completeNum = %s", - mStartThreadNum, mStopNum, mCancelNum, mFailNum, mCompleteNum)); + "startThreadNum = %s, stopNum = %s, cancelNum = %s, failNum = %s, completeNum = %s, flagQueueSize = %s", + startThreadNum, stopNum, cancelNum, failNum, mCompleteNum, mFlagQueue.size())); } } @@ -300,19 +613,19 @@ public class M3U8VodLoader extends BaseM3U8Loader { ITsMergeHandler mergeHandler = mTaskWrapper.asM3U8().getMergeHandler(); String cacheDir = getCacheDir(); List partPath = new ArrayList<>(); - for (ThreadRecord tr : mTaskRecord.threadRecords) { + for (ThreadRecord tr : taskRecord.threadRecords) { partPath.add(getTsFilePath(cacheDir, tr.threadId)); } boolean isSuccess; if (mergeHandler != null) { isSuccess = mergeHandler.merge(mTaskWrapper.asM3U8().getKeyInfo(), partPath); } else { - isSuccess = FileUtil.mergeFile(mTaskRecord.filePath, partPath); + isSuccess = FileUtil.mergeFile(taskRecord.filePath, partPath); } if (isSuccess) { // 合并成功,删除缓存文件 - for (String pp : partPath) { - File f = new File(pp); + File[] files = new File(cacheDir).listFiles(); + for (File f : files) { if (f.exists()) { f.delete(); } @@ -328,4 +641,9 @@ public class M3U8VodLoader extends BaseM3U8Loader { } } } + + private static class TempFlag { + AbsThreadTask threadTask; + int threadId; + } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8VodUtil.java b/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8VodUtil.java index edca7953..c5b6b29d 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8VodUtil.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8VodUtil.java @@ -20,10 +20,11 @@ import com.arialyy.aria.core.common.CompleteInfo; import com.arialyy.aria.core.common.IUtil; import com.arialyy.aria.core.common.OnFileInfoCallback; import com.arialyy.aria.core.download.DTaskWrapper; +import com.arialyy.aria.core.download.M3U8Listener; import com.arialyy.aria.core.inf.AbsEntity; -import com.arialyy.aria.core.inf.IDownloadListener; import com.arialyy.aria.exception.BaseException; import com.arialyy.aria.exception.M3U8Exception; +import com.arialyy.aria.util.ALog; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -40,12 +41,12 @@ public class M3U8VodUtil implements IUtil { private final String TAG = "M3U8DownloadUtil"; private DTaskWrapper mWrapper; - private IDownloadListener mListener; + private M3U8Listener mListener; private boolean isStop = false, isCancel = false; private List mUrls = new ArrayList<>(); private M3U8VodLoader mLoader; - public M3U8VodUtil(DTaskWrapper wrapper, IDownloadListener listener) { + public M3U8VodUtil(DTaskWrapper wrapper, M3U8Listener listener) { mWrapper = wrapper; mListener = listener; mLoader = new M3U8VodLoader(mListener, mWrapper); @@ -85,10 +86,6 @@ public class M3U8VodUtil implements IUtil { getVodInfo(); } - @Override public void setMaxSpeed(int speed) { - mLoader.setMaxSpeed(speed); - } - /** * 获取点播文件信息 */ @@ -114,7 +111,13 @@ public class M3U8VodUtil implements IUtil { return; } mWrapper.asM3U8().setUrls(mUrls); - mLoader.start(); + if (isStop) { + mListener.onStop(mWrapper.getEntity().getCurrentProgress()); + } else if (isCancel) { + mListener.onCancel(); + } else { + mLoader.start(); + } } @Override public void onFail(AbsEntity entity, BaseException e, boolean needRetry) { @@ -129,5 +132,6 @@ public class M3U8VodUtil implements IUtil { return; } mListener.onFail(needRetry, e); + mLoader.onDestroy(); } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/event/Event.java b/Aria/src/main/java/com/arialyy/aria/core/event/Event.java new file mode 100644 index 00000000..f2366ea4 --- /dev/null +++ b/Aria/src/main/java/com/arialyy/aria/core/event/Event.java @@ -0,0 +1,30 @@ +/* + * 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.event; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 注解需要接收消息的方法,方法中只能有一个参数 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface Event { + //Class value(); +} diff --git a/Aria/src/main/java/com/arialyy/aria/core/scheduler/IDownloadSchedulerListener.java b/Aria/src/main/java/com/arialyy/aria/core/event/EventMethodInfo.java similarity index 69% rename from Aria/src/main/java/com/arialyy/aria/core/scheduler/IDownloadSchedulerListener.java rename to Aria/src/main/java/com/arialyy/aria/core/event/EventMethodInfo.java index d685697d..85db3707 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/scheduler/IDownloadSchedulerListener.java +++ b/Aria/src/main/java/com/arialyy/aria/core/event/EventMethodInfo.java @@ -13,17 +13,20 @@ * 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; +package com.arialyy.aria.core.event; /** - * Created by lyy on 2017/4/5. + * 事件消息信息 */ -public interface IDownloadSchedulerListener extends ISchedulerListener { +class EventMethodInfo { + + /** + * 被{@link Event}注解的事件方法 + */ + String methodName; /** - * 支持断点的回调 + * 该方法对应的参数类型 */ - public void onNoSupportBreakPoint(TASK task); + Class param; } diff --git a/Aria/src/main/java/com/arialyy/aria/core/event/EventMsgUtil.java b/Aria/src/main/java/com/arialyy/aria/core/event/EventMsgUtil.java new file mode 100644 index 00000000..7e3cb342 --- /dev/null +++ b/Aria/src/main/java/com/arialyy/aria/core/event/EventMsgUtil.java @@ -0,0 +1,153 @@ +/* + * 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.event; + +import com.arialyy.aria.util.ALog; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +/** + * 消息发送工具 + */ +public class EventMsgUtil { + private static final String TAG = "EventUtil"; + private static EventMsgUtil defaultInstance; + private Map> mEventMethods = + new ConcurrentHashMap<>(); + private ArrayBlockingQueue mEventQueue = new ArrayBlockingQueue<>(10); + private ExecutorService mPool = Executors.newFixedThreadPool(10); + + private EventMsgUtil() { + ExecutorService pool = Executors.newSingleThreadExecutor(); + pool.execute(new Runnable() { + @Override public void run() { + while (true) { + try { + Object info = mEventQueue.take(); + sendEvent(info); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + }); + } + + private void sendEvent(final Object param) { + mPool.submit(new Runnable() { + @Override public void run() { + Set keys = mEventMethods.keySet(); + for (Object key : keys) { + List list = mEventMethods.get(key); + if (list != null && !list.isEmpty()) { + for (EventMethodInfo info : list) { + try { + if (info.param == param.getClass()) { + Method method = key.getClass().getDeclaredMethod(info.methodName, info.param); + method.setAccessible(true); + method.invoke(key, param); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + } + }); + } + + public static EventMsgUtil getDefault() { + if (defaultInstance == null) { + synchronized (EventMsgUtil.class) { + if (defaultInstance == null) { + defaultInstance = new EventMsgUtil(); + } + } + } + return defaultInstance; + } + + /** + * 注册事件 + */ + public void register(Object obj) { + Method[] methods = obj.getClass().getDeclaredMethods(); + for (Method method : methods) { + method.setAccessible(true); + if (method.getAnnotation(Event.class) == null) { + continue; + } + Class[] clazz = method.getParameterTypes(); + if (clazz.length == 0 || clazz.length > 1) { + ALog.e(TAG, + String.format("%s.%s参数数量为0或参数数量大于1", obj.getClass().getName(), method.getName())); + continue; + } + int modifier = method.getModifiers(); + if (Modifier.isStatic(modifier) || Modifier.isAbstract(modifier) || Modifier.isFinal( + modifier)) { + ALog.e(TAG, "注册的方法不能使用final、static、abstract修饰"); + continue; + } + + EventMethodInfo methodInfo = new EventMethodInfo(); + methodInfo.methodName = method.getName(); + methodInfo.param = clazz[0]; + List list = mEventMethods.get(obj); + if (list == null) { + list = new ArrayList<>(); + mEventMethods.put(obj, list); + } + list.add(methodInfo); + } + } + + public void unRegister(Object obj) { + for (Iterator>> iter = + mEventMethods.entrySet().iterator(); iter.hasNext(); ) { + Map.Entry> entry = iter.next(); + if (entry.getKey().equals(obj)) { + entry.getValue().clear(); + iter.remove(); + } + } + } + + /** + * 发送事件,接收消息的方法需要使用{@link Event}注解 + */ + public void post(Object param) { + + synchronized (EventMsgUtil.class) { + try { + mEventQueue.offer(param, 2, TimeUnit.SECONDS); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } +} diff --git a/Aria/src/main/java/com/arialyy/aria/core/event/PeerIndexEvent.java b/Aria/src/main/java/com/arialyy/aria/core/event/PeerIndexEvent.java new file mode 100644 index 00000000..23a3f38e --- /dev/null +++ b/Aria/src/main/java/com/arialyy/aria/core/event/PeerIndexEvent.java @@ -0,0 +1,27 @@ +/* + * 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.event; + +public class PeerIndexEvent { + + public int peerIndex; + public long createTime; + + public PeerIndexEvent(int peerIndex) { + this.peerIndex = peerIndex; + createTime = System.currentTimeMillis(); + } +} diff --git a/Aria/src/main/java/com/arialyy/aria/core/event/SpeedEvent.java b/Aria/src/main/java/com/arialyy/aria/core/event/SpeedEvent.java new file mode 100644 index 00000000..8feb7f59 --- /dev/null +++ b/Aria/src/main/java/com/arialyy/aria/core/event/SpeedEvent.java @@ -0,0 +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.event; + +public class SpeedEvent { + + public int speed; + + public SpeedEvent(int speed) { + this.speed = speed; + } +} diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTarget.java b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTarget.java index c3c1aa03..9911e239 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTarget.java +++ b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTarget.java @@ -19,14 +19,13 @@ import android.os.Handler; import android.os.Looper; import android.support.annotation.CheckResult; import android.text.TextUtils; -import com.arialyy.aria.core.AriaManager; +import com.arialyy.aria.core.command.CancelCmd; import com.arialyy.aria.core.command.ICmd; -import com.arialyy.aria.core.command.normal.CancelCmd; -import com.arialyy.aria.core.command.normal.NormalCmdFactory; -import com.arialyy.aria.core.command.normal.ReStartCmd; +import com.arialyy.aria.core.command.NormalCmdFactory; import com.arialyy.aria.core.download.DGTaskWrapper; -import com.arialyy.aria.core.download.DownloadGroupEntity; import com.arialyy.aria.core.download.DTaskWrapper; +import com.arialyy.aria.core.download.DownloadGroupEntity; +import com.arialyy.aria.core.event.EventMsgUtil; import com.arialyy.aria.core.manager.TaskWrapperManager; import com.arialyy.aria.core.scheduler.DownloadGroupSchedulers; import com.arialyy.aria.core.scheduler.DownloadSchedulers; @@ -36,8 +35,6 @@ import com.arialyy.aria.core.upload.UTaskWrapper; import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.CommonUtil; import com.arialyy.aria.util.RecordUtil; -import java.util.ArrayList; -import java.util.List; /** * Created by AriaL on 2017/7/3. @@ -81,7 +78,8 @@ public abstract class AbsTarget implements ITargetHand if (mEntity instanceof AbsNormalEntity) { RecordUtil.delTaskRecord((AbsNormalEntity) mEntity, mTaskWrapper.isRemoveFile()); } else if (mEntity instanceof DownloadGroupEntity) { - RecordUtil.delGroupTaskRecord(((DownloadGroupEntity) mEntity), mTaskWrapper.isRemoveFile(), true); + RecordUtil.delGroupTaskRecord(((DownloadGroupEntity) mEntity), mTaskWrapper.isRemoveFile(), + true); } TaskWrapperManager.getInstance().removeTaskWrapper(mEntity.getKey()); } @@ -272,10 +270,9 @@ public abstract class AbsTarget implements ITargetHand */ @Override public void add() { if (checkConfig()) { - AriaManager.getInstance(AriaManager.APP) - .setCmd(CommonUtil.createNormalCmd(getTaskWrapper(), NormalCmdFactory.TASK_CREATE, - checkTaskType())) - .exe(); + EventMsgUtil.getDefault() + .post(CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_CREATE, + checkTaskType())); } } @@ -284,11 +281,9 @@ public abstract class AbsTarget implements ITargetHand */ @Override public void start() { if (checkConfig()) { - AriaManager.getInstance(AriaManager.APP) - .setCmd( - CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_START, - checkTaskType())) - .exe(); + EventMsgUtil.getDefault() + .post(CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_START, + checkTaskType())); } } @@ -298,17 +293,14 @@ public abstract class AbsTarget implements ITargetHand * @see #stop() */ @Deprecated public void pause() { - if (checkConfig()) { - stop(); - } + stop(); } @Override public void stop() { if (checkConfig()) { - AriaManager.getInstance(AriaManager.APP) - .setCmd( - CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_STOP, checkTaskType())) - .exe(); + EventMsgUtil.getDefault() + .post(CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_STOP, + checkTaskType())); } } @@ -317,11 +309,9 @@ public abstract class AbsTarget implements ITargetHand */ @Override public void resume() { if (checkConfig()) { - AriaManager.getInstance(AriaManager.APP) - .setCmd( - CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_START, - checkTaskType())) - .exe(); + EventMsgUtil.getDefault() + .post(CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_START, + checkTaskType())); } } @@ -330,10 +320,9 @@ public abstract class AbsTarget implements ITargetHand */ @Override public void cancel() { if (checkConfig()) { - AriaManager.getInstance(AriaManager.APP) - .setCmd(CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_CANCEL, - checkTaskType())) - .exe(); + EventMsgUtil.getDefault() + .post(CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_CANCEL, + checkTaskType())); } } @@ -342,12 +331,11 @@ public abstract class AbsTarget implements ITargetHand */ @Override public void reTry() { if (checkConfig()) { - List cmds = new ArrayList<>(); int taskType = checkTaskType(); - cmds.add( - CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_STOP, taskType)); - cmds.add(CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_START, taskType)); - AriaManager.getInstance(AriaManager.APP).setCmds(cmds).exe(); + EventMsgUtil.getDefault() + .post(CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_STOP, taskType)); + EventMsgUtil.getDefault() + .post(CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_START, taskType)); } } @@ -363,7 +351,7 @@ public abstract class AbsTarget implements ITargetHand (CancelCmd) CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_CANCEL, checkTaskType()); cancelCmd.removeFile = removeFile; - AriaManager.getInstance(AriaManager.APP).setCmd(cancelCmd).exe(); + EventMsgUtil.getDefault().post(cancelCmd); } } @@ -372,10 +360,9 @@ public abstract class AbsTarget implements ITargetHand */ @Override public void reStart() { if (checkConfig()) { - ReStartCmd cmd = - (ReStartCmd) CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_RESTART, - checkTaskType()); - AriaManager.getInstance(AriaManager.APP).setCmd(cmd).exe(); + EventMsgUtil.getDefault() + .post(CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_RESTART, + checkTaskType())); } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTask.java b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTask.java index 71305430..fc206bd2 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTask.java +++ b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTask.java @@ -100,17 +100,6 @@ public abstract class AbsTask return mExpand.get(key); } - /** - * 设置最大下载/上传速度 - * - * @param speed 单位为:kb - */ - public void setMaxSpeed(int speed) { - if (getUtil() != null) { - getUtil().setMaxSpeed(speed); - } - } - /** * 任务是否完成 * @@ -215,12 +204,7 @@ public abstract class AbsTask @Override public void stop(@TaskSchedulerType int type) { isStop = true; mSchedulerType = type; - if (getUtil().isRunning()) { - getUtil().stop(); - } else { - ALog.d(TAG, "下载任务未执行"); - mListener.onStop(mTaskWrapper.getEntity().getCurrentProgress()); - } + getUtil().stop(); } @Override public void cancel() { @@ -230,11 +214,7 @@ public abstract class AbsTask @Override public void cancel(@TaskSchedulerType int type) { isCancel = true; mSchedulerType = type; - if (!getUtil().isRunning()) { - mListener.onCancel(); - } else { - getUtil().cancel(); - } + getUtil().cancel(); } /** diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/IHttpFileLenAdapter.java b/Aria/src/main/java/com/arialyy/aria/core/inf/IHttpFileLenAdapter.java index 48202fd3..55b8c507 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/inf/IHttpFileLenAdapter.java +++ b/Aria/src/main/java/com/arialyy/aria/core/inf/IHttpFileLenAdapter.java @@ -23,7 +23,7 @@ import java.util.Map; /** * Http文件长度适配器 */ -public class IHttpFileLenAdapter implements Serializable { +public interface IHttpFileLenAdapter extends Serializable { long serialVersionUID = 1L; /** @@ -32,7 +32,5 @@ public class IHttpFileLenAdapter implements Serializable { * @param headers header参数{@link URLConnection#getHeaderFields()} * @return 文件长度 */ - public long handleFileLen(Map> headers) { - return 0; - } + long handleFileLen(Map> headers); } 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 d704ce17..2cdc9d61 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 @@ -41,10 +41,14 @@ public interface ITask { * 组合任务的子任务 */ int DOWNLOAD_GROUP_SUB = 4; + /** + * 切片任务 + */ + int M3U8_PEER = 5; /** * 填充的 */ - int TEMP = 5; + int TEMP = 6; /** * 未知 */ diff --git a/Aria/src/main/java/com/arialyy/aria/core/manager/DTaskWrapperFactory.java b/Aria/src/main/java/com/arialyy/aria/core/manager/DTaskWrapperFactory.java index e0625997..55d2b9d9 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/manager/DTaskWrapperFactory.java +++ b/Aria/src/main/java/com/arialyy/aria/core/manager/DTaskWrapperFactory.java @@ -70,9 +70,9 @@ class DTaskWrapperFactory implements INormalTEFactory temp = mThreadTasks.get(key); @@ -152,8 +151,9 @@ public class ThreadTaskManager { } } if (tempC != null) { - task.setInterrupted(true); + task.destroy(); temp.remove(tempC); + return true; } } } catch (Exception e) { @@ -161,6 +161,7 @@ public class ThreadTaskManager { } finally { LOCK.unlock(); } + return false; } /** @@ -176,7 +177,7 @@ public class ThreadTaskManager { return; } try { - if (task == null || task.isInterrupted()) { + if (task == null || task.isDestroy()) { ALog.e(TAG, "线程为空或线程已经中断"); return; } diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/AbsTaskQueue.java b/Aria/src/main/java/com/arialyy/aria/core/queue/AbsTaskQueue.java index a58ce821..98ab974f 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/queue/AbsTaskQueue.java +++ b/Aria/src/main/java/com/arialyy/aria/core/queue/AbsTaskQueue.java @@ -23,14 +23,13 @@ import com.arialyy.aria.core.inf.AbsTaskWrapper; import com.arialyy.aria.core.inf.IEntity; import com.arialyy.aria.core.inf.TaskSchedulerType; import com.arialyy.aria.core.manager.TaskWrapperManager; +import com.arialyy.aria.core.manager.ThreadTaskManager; import com.arialyy.aria.core.queue.pool.BaseCachePool; import com.arialyy.aria.core.queue.pool.BaseExecutePool; import com.arialyy.aria.core.queue.pool.DownloadSharePool; import com.arialyy.aria.core.queue.pool.UploadSharePool; import com.arialyy.aria.core.upload.UploadTask; import com.arialyy.aria.util.ALog; -import java.util.Map; -import java.util.Set; /** * Created by lyy on 2017/2/23. 任务队列 @@ -62,7 +61,11 @@ public abstract class AbsTaskQueue tasks = mExecutePool.getAllTask(); - Set keys = tasks.keySet(); - for (String key : keys) { - TASK task = tasks.get(key); - task.setMaxSpeed(maxSpeed); - } - } - /** * 获取配置文件旧的最大任务数 */ @@ -208,7 +199,7 @@ public abstract class AbsTaskQueue public static DownloadTaskQueue getInstance() { if (INSTANCE == null) { - synchronized (AriaManager.LOCK) { + synchronized (DownloadTaskQueue.class) { INSTANCE = new DownloadTaskQueue(); } } 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 0bf1d8fe..4379ee61 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 @@ -16,7 +16,6 @@ package com.arialyy.aria.core.queue; -import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.download.DGTaskWrapper; import com.arialyy.aria.core.download.DTaskWrapper; import com.arialyy.aria.core.download.DownloadGroupTask; @@ -43,7 +42,7 @@ class TaskFactory { public static TaskFactory getInstance() { if (INSTANCE == null) { - synchronized (AriaManager.LOCK) { + synchronized (TaskFactory.class) { INSTANCE = new TaskFactory(); } } 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 5ccbff43..b2f541e4 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 @@ -31,7 +31,7 @@ public class UploadTaskQueue extends AbsTaskQueue { public static UploadTaskQueue getInstance() { if (INSTANCE == null) { - synchronized (AriaManager.LOCK) { + synchronized (UploadTaskQueue.class) { INSTANCE = new UploadTaskQueue(); } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/pool/BaseCachePool.java b/Aria/src/main/java/com/arialyy/aria/core/queue/pool/BaseCachePool.java index d2ea1c88..5a5a96de 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/queue/pool/BaseCachePool.java +++ b/Aria/src/main/java/com/arialyy/aria/core/queue/pool/BaseCachePool.java @@ -17,7 +17,6 @@ package com.arialyy.aria.core.queue.pool; import android.text.TextUtils; -import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.inf.AbsTask; import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.CommonUtil; @@ -35,6 +34,7 @@ public class BaseCachePool implements IPool { private static final String TAG = "BaseCachePool"; private static final int MAX_NUM = Integer.MAX_VALUE; //最大下载任务数 private static final long TIME_OUT = 1000; + private static final Object LOCK = new Object(); private Map mCacheMap; private LinkedBlockingQueue mCacheQueue; @@ -82,7 +82,7 @@ public class BaseCachePool implements IPool { } @Override public boolean putTask(TASK task) { - synchronized (AriaManager.LOCK) { + synchronized (LOCK) { if (task == null) { ALog.e(TAG, "任务不能为空!!"); return false; @@ -103,7 +103,7 @@ public class BaseCachePool implements IPool { } @Override public TASK pollTask() { - synchronized (AriaManager.LOCK) { + synchronized (LOCK) { try { TASK task; task = mCacheQueue.poll(TIME_OUT, TimeUnit.MICROSECONDS); @@ -120,7 +120,7 @@ public class BaseCachePool implements IPool { } @Override public TASK getTask(String key) { - synchronized (AriaManager.LOCK) { + synchronized (LOCK) { if (TextUtils.isEmpty(key)) { ALog.e(TAG, "key 为null"); return null; @@ -134,7 +134,7 @@ public class BaseCachePool implements IPool { } @Override public boolean removeTask(TASK task) { - synchronized (AriaManager.LOCK) { + synchronized (LOCK) { if (task == null) { ALog.e(TAG, "任务不能为空"); return false; @@ -147,7 +147,7 @@ public class BaseCachePool implements IPool { } @Override public boolean removeTask(String key) { - synchronized (AriaManager.LOCK) { + synchronized (LOCK) { if (TextUtils.isEmpty(key)) { ALog.e(TAG, "请传入有效的下载链接"); return false; diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/pool/BaseExecutePool.java b/Aria/src/main/java/com/arialyy/aria/core/queue/pool/BaseExecutePool.java index 8996248c..05c17124 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/queue/pool/BaseExecutePool.java +++ b/Aria/src/main/java/com/arialyy/aria/core/queue/pool/BaseExecutePool.java @@ -31,6 +31,7 @@ import java.util.concurrent.TimeUnit; */ public class BaseExecutePool implements IPool { private final String TAG = "BaseExecutePool"; + private static final Object LOCK = new Object(); final long TIME_OUT = 1000; ArrayBlockingQueue mExecuteQueue; Map mExecuteMap; @@ -59,7 +60,7 @@ public class BaseExecutePool implements IPool { } @Override public boolean putTask(TASK task) { - synchronized (AriaManager.LOCK) { + synchronized (LOCK) { if (task == null) { ALog.e(TAG, "任务不能为空!!"); return false; @@ -86,7 +87,7 @@ public class BaseExecutePool implements IPool { * @param maxNum 下载数 */ public void setMaxNum(int maxNum) { - synchronized (AriaManager.LOCK) { + synchronized (LOCK) { try { ArrayBlockingQueue temp = new ArrayBlockingQueue<>(maxNum); TASK task; @@ -107,7 +108,7 @@ public class BaseExecutePool implements IPool { * @param newTask 新任务 */ boolean putNewTask(TASK newTask) { - synchronized (AriaManager.LOCK) { + synchronized (LOCK) { String url = newTask.getKey(); boolean s = mExecuteQueue.offer(newTask); ALog.d(TAG, "任务【" + newTask.getTaskName() + "】进入执行队列" + (s ? "成功" : "失败")); @@ -122,7 +123,7 @@ public class BaseExecutePool implements IPool { * 队列满时,将移除下载队列中的第一个任务 */ boolean pollFirstTask() { - synchronized (AriaManager.LOCK) { + synchronized (LOCK) { try { TASK oldTask = mExecuteQueue.poll(TIME_OUT, TimeUnit.MICROSECONDS); if (oldTask == null) { @@ -141,7 +142,7 @@ public class BaseExecutePool implements IPool { } @Override public TASK pollTask() { - synchronized (AriaManager.LOCK) { + synchronized (LOCK) { try { TASK task; task = mExecuteQueue.poll(TIME_OUT, TimeUnit.MICROSECONDS); @@ -158,7 +159,7 @@ public class BaseExecutePool implements IPool { } @Override public TASK getTask(String key) { - synchronized (AriaManager.LOCK) { + synchronized (LOCK) { if (TextUtils.isEmpty(key)) { ALog.e(TAG, "key 为null"); return null; @@ -172,7 +173,7 @@ public class BaseExecutePool implements IPool { } @Override public boolean removeTask(TASK task) { - synchronized (AriaManager.LOCK) { + synchronized (LOCK) { if (task == null) { ALog.e(TAG, "任务不能为空"); return false; @@ -183,7 +184,7 @@ public class BaseExecutePool implements IPool { } @Override public boolean removeTask(String key) { - synchronized (AriaManager.LOCK) { + synchronized (LOCK) { if (TextUtils.isEmpty(key)) { ALog.e(TAG, "key 为null"); return false; diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/pool/DownloadExecutePool.java b/Aria/src/main/java/com/arialyy/aria/core/queue/pool/DownloadExecutePool.java index db3b6c83..25fcbcb0 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/queue/pool/DownloadExecutePool.java +++ b/Aria/src/main/java/com/arialyy/aria/core/queue/pool/DownloadExecutePool.java @@ -34,7 +34,7 @@ class DownloadExecutePool extends BaseExecutePool { } @Override public boolean putTask(TASK task) { - synchronized (AriaManager.LOCK) { + synchronized (DownloadExecutePool.class) { if (task == null) { ALog.e(TAG, "任务不能为空!!"); return false; diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/pool/DownloadSharePool.java b/Aria/src/main/java/com/arialyy/aria/core/queue/pool/DownloadSharePool.java index cd7625bd..4c07a16e 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/queue/pool/DownloadSharePool.java +++ b/Aria/src/main/java/com/arialyy/aria/core/queue/pool/DownloadSharePool.java @@ -15,8 +15,6 @@ */ package com.arialyy.aria.core.queue.pool; -import com.arialyy.aria.core.AriaManager; - /** * Created by Aria.Lao on 2017/7/17. * 下载任务池,该池子为简单任务和任务组共用 @@ -34,7 +32,7 @@ public class DownloadSharePool { public static DownloadSharePool getInstance() { if (INSTANCE == null) { - synchronized (AriaManager.LOCK) { + synchronized (DownloadSharePool.class) { INSTANCE = new DownloadSharePool(); } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/pool/UploadSharePool.java b/Aria/src/main/java/com/arialyy/aria/core/queue/pool/UploadSharePool.java index f75af152..68c63d2b 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/queue/pool/UploadSharePool.java +++ b/Aria/src/main/java/com/arialyy/aria/core/queue/pool/UploadSharePool.java @@ -15,8 +15,6 @@ */ package com.arialyy.aria.core.queue.pool; -import com.arialyy.aria.core.AriaManager; - /** * Created by Aria.Lao on 2017/7/17. * 下载任务池,该池子为简单任务和任务组共用 @@ -34,7 +32,7 @@ public class UploadSharePool { public static UploadSharePool getInstance() { if (INSTANCE == null) { - synchronized (AriaManager.LOCK) { + synchronized (UploadSharePool.class) { INSTANCE = new UploadSharePool(); } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/scheduler/AbsSchedulers.java b/Aria/src/main/java/com/arialyy/aria/core/scheduler/AbsSchedulers.java index b51c14a7..612f63a7 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/scheduler/AbsSchedulers.java +++ b/Aria/src/main/java/com/arialyy/aria/core/scheduler/AbsSchedulers.java @@ -17,8 +17,8 @@ package com.arialyy.aria.core.scheduler; import android.content.Intent; import android.os.Bundle; -import android.os.CountDownTimer; import android.os.Message; +import com.arialyy.annotations.TaskEnum; import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.download.DownloadGroupTask; import com.arialyy.aria.core.download.DownloadTask; @@ -51,14 +51,7 @@ abstract class AbsSchedulers> mObservers = - new ConcurrentHashMap<>(); - - /** - * 设置代理类后缀名 - */ - abstract String getProxySuffix(); - + private Map> mObservers = new ConcurrentHashMap<>(); private AriaManager manager; AbsSchedulers() { @@ -69,21 +62,39 @@ abstract class AbsSchedulers listener = mObservers.get(getKey(obj)); - if (listener == null) { - listener = createListener(targetName); + Map listeners = mObservers.get(getKey(obj)); + + if (listeners == null) { + listeners = new ConcurrentHashMap<>(); + mObservers.put(getKey(obj), listeners); + } + String proxyClassName = targetName + taskEnum.proxySuffix; + + if (!hasProxyListener(listeners, taskEnum)) { + ISchedulerListener listener = createListener(proxyClassName); if (listener != null) { listener.setListener(obj); - mObservers.put(getKey(obj), listener); + listeners.put(taskEnum, listener); } else { - ALog.e(TAG, "注册错误,没有【" + targetName + "】观察者"); + ALog.e(TAG, "注册错误,没有【" + proxyClassName + "】观察者"); } } } + /** + * 检查当前类是否已经注册了对应的代理 + * + * @param taskEnum 代理类类型 + * @return true,已注册代理类,false,没有注册代理类 + */ + private boolean hasProxyListener(Map listeners, TaskEnum taskEnum) { + return !listeners.isEmpty() && listeners.get(taskEnum) != null; + } + /** * 移除注册 * @@ -93,9 +104,10 @@ abstract class AbsSchedulers>> iter = + for (Iterator>> iter = mObservers.entrySet().iterator(); iter.hasNext(); ) { - Map.Entry> entry = iter.next(); + Map.Entry> entry = iter.next(); + if (entry.getKey().equals(getKey(obj))) { iter.remove(); } @@ -109,15 +121,15 @@ abstract class AbsSchedulers createListener(String targetName) { - AbsSchedulerListener listener = null; + private ISchedulerListener createListener(String proxyClassName) { + ISchedulerListener listener = null; try { - Class clazz = Class.forName(targetName + getProxySuffix()); - listener = (AbsSchedulerListener) clazz.newInstance(); + Class clazz = Class.forName(proxyClassName); + listener = (ISchedulerListener) clazz.newInstance(); } catch (ClassNotFoundException e) { - ALog.e(TAG, targetName + ",没有Aria的Download或Upload注解方法"); + ALog.e(TAG, e.getMessage()); } catch (InstantiationException e) { ALog.e(TAG, e.getMessage()); } catch (IllegalAccessException e) { @@ -131,6 +143,10 @@ abstract class AbsSchedulers 0) { + Set keys = mObservers.keySet(); + for (String key : keys) { + Map listeners = mObservers.get(key); + if (listeners == null || listeners.isEmpty()) { + continue; + } + M3U8PeerTaskListener listener = + (M3U8PeerTaskListener) listeners.get(TaskEnum.M3U8_PEER); + if (listener == null) { + continue; + } + + switch (msg.what) { + case M3U8_PEER_START: + listener.onPeerStart(data.getString(DATA_M3U8_URL), + data.getString(DATA_M3U8_PEER_PATH), + data.getInt(DATA_M3U8_PEER_INDEX)); + break; + case M3U8_PEER_COMPLETE: + listener.onPeerComplete(data.getString(DATA_M3U8_URL), + data.getString(DATA_M3U8_PEER_PATH), + data.getInt(DATA_M3U8_PEER_INDEX)); + break; + case M3U8_PEER_FAIL: + listener.onPeerFail(data.getString(DATA_M3U8_URL), + data.getString(DATA_M3U8_PEER_PATH), + data.getInt(DATA_M3U8_PEER_INDEX)); + break; + } + } + } + + boolean canSend = manager.getAppConfig().isUseBroadcast(); + if (canSend) { + Intent intent = new Intent(ISchedulers.ARIA_TASK_INFO_ACTION); + intent.putExtras(data); + AriaManager.APP.sendBroadcast(intent); + } + + return true; + } + /** * 处理任务组子任务事件 */ @@ -148,7 +212,15 @@ abstract class AbsSchedulers 0) { Set keys = mObservers.keySet(); for (String key : keys) { - AbsSchedulerListener listener = mObservers.get(key); + Map listeners = mObservers.get(key); + if (listeners == null || listeners.isEmpty()) { + continue; + } + SubTaskListener listener = + (SubTaskListener) listeners.get(TaskEnum.DOWNLOAD_GROUP_SUB); + if (listener == null) { + continue; + } switch (msg.what) { case SUB_PRE: listener.onSubTaskPre((TASK) params.groupTask, params.entity); @@ -228,7 +300,7 @@ abstract class AbsSchedulers 0) { Set keys = mObservers.keySet(); for (String key : keys) { - callback(state, task, mObservers.get(key)); + Map listeners = mObservers.get(key); + if (listeners == null || listeners.isEmpty()) { + continue; + } + NormalTaskListener listener = null; + if (mObservers.get(key) != null) { + if (task instanceof DownloadTask) { + listener = (NormalTaskListener) listeners.get(TaskEnum.DOWNLOAD); + } else if (task instanceof DownloadGroupTask) { + listener = (NormalTaskListener) listeners.get(TaskEnum.DOWNLOAD_GROUP); + } else if (task instanceof UploadTask) { + listener = (NormalTaskListener) listeners.get(TaskEnum.UPLOAD); + } + } + if (listener != null) { + normalTaskCallback(state, task, listener); + } } } } - private void callback(int state, TASK task, - AbsSchedulerListener listener) { + private void normalTaskCallback(int state, TASK task, NormalTaskListener listener) { if (listener != null) { if (task == null) { ALog.e(TAG, "TASK 为null,回调失败"); @@ -341,7 +428,7 @@ abstract class AbsSchedulers { - - /** - * 队列已经满了,继续创建任务,将会回调该方法 - */ - void onWait(TASK task); - - /** - * 预处理,有时有些地址链接比较慢,这时可以先在这个地方出来一些界面上的UI,如按钮的状态。 - * 在这个回调中,任务是获取不到文件大小,下载速度等参数 - */ - void onPre(TASK task); - - /** - * 任务预加载完成 - */ - void onTaskPre(TASK task); - - /** - * 任务恢复下载 - */ - void onTaskResume(TASK task); - - /** - * 任务开始 - */ - void onTaskStart(TASK task); - - /** - * 任务停止 - */ - void onTaskStop(TASK task); - - /** - * 任务取消 - */ - void onTaskCancel(TASK task); - - /** - * 任务失败 - * - * @deprecated {@link #onTaskFail(ITask, Exception)} - */ - @Deprecated - void onTaskFail(TASK task); - - /** - * 任务失败 - */ - void onTaskFail(TASK task, Exception e); - - /** - * 任务完成 - */ - void onTaskComplete(TASK task); +public interface ISchedulerListener { - /** - * 任务执行中 - */ - void onTaskRunning(TASK task); + void setListener(Object obj); } \ No newline at end of file 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 181570bc..13dac503 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 @@ -19,7 +19,6 @@ package com.arialyy.aria.core.scheduler; import android.os.Handler; import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.download.DownloadGroupEntity; -import com.arialyy.aria.core.inf.AbsTask; import com.arialyy.aria.core.inf.ITask; import com.arialyy.aria.core.upload.UploadEntity; @@ -64,10 +63,28 @@ public interface ISchedulers extends Handler.Callback { String TASK_PERCENT = "ARIA_TASK_PERCENT"; /** - * 为组合任务任务 + * M3U8地址 + */ + String DATA_M3U8_URL = "DATA_M3U8_URL"; + /** + * 当前下载完成的切片地址 + */ + String DATA_M3U8_PEER_PATH = "DATA_M3U8_PEER_PATH"; + /** + * 当前下载完成的切片索引 + */ + String DATA_M3U8_PEER_INDEX = "DATA_M3U8_PEER_INDEX"; + + /** + * 组合任务任务标志 */ int IS_SUB_TASK = 0xd1; + /** + * m3u8切片任务标志 + */ + int IS_M3U8_PEER = 0xd2; + /** * 任务不支持断点 */ @@ -148,4 +165,17 @@ public interface ISchedulers extends Handler.Callback { * 组合任务子任务完成 */ int SUB_COMPLETE = 0xa7; + + /** + * M3U8切片开始下载 + */ + int M3U8_PEER_START = 0xb1; + /** + * M3U8切片下载完成 + */ + int M3U8_PEER_COMPLETE = 0xb2; + /** + * M3U8切片下载失败 + */ + int M3U8_PEER_FAIL = 0xb3; } \ No newline at end of file diff --git a/Aria/src/main/java/com/arialyy/aria/core/scheduler/M3U8PeerTaskListener.java b/Aria/src/main/java/com/arialyy/aria/core/scheduler/M3U8PeerTaskListener.java new file mode 100644 index 00000000..3df14066 --- /dev/null +++ b/Aria/src/main/java/com/arialyy/aria/core/scheduler/M3U8PeerTaskListener.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.arialyy.aria.core.scheduler; + +/** + * Created by Aria.Lao on 2019/6/26. + * m3u8切片事件回调类 + */ +public class M3U8PeerTaskListener implements ISchedulerListener { + + public void onPeerStart(final String m3u8Url, final String peerPath, final int peerIndex) { + } + + public void onPeerComplete(final String m3u8Url, final String peerPath, final int peerIndex) { + } + + public void onPeerFail(final String m3u8Url, final String peerPath, final int peerIndex) { + } + + @Override public void setListener(Object obj) { + + } +} \ No newline at end of file diff --git a/Aria/src/main/java/com/arialyy/aria/core/scheduler/NormalTaskListener.java b/Aria/src/main/java/com/arialyy/aria/core/scheduler/NormalTaskListener.java new file mode 100644 index 00000000..08b1a8bf --- /dev/null +++ b/Aria/src/main/java/com/arialyy/aria/core/scheduler/NormalTaskListener.java @@ -0,0 +1,116 @@ +/* + * 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.download.DownloadGroupTask; +import com.arialyy.aria.core.download.DownloadTask; +import com.arialyy.aria.core.inf.ITask; +import com.arialyy.aria.core.upload.UploadTask; + +/** + * Created by Aria.Lao on 2017/6/7. + * 普通任务事件{@link DownloadTask}、{@link UploadTask}、{@link DownloadGroupTask}回调类 + */ +public class NormalTaskListener implements ISchedulerListener { + + /** + * 队列已经满了,继续创建任务,将会回调该方法 + */ + public void onWait(TASK task) { + + } + + /** + * 预处理,有时有些地址链接比较慢,这时可以先在这个地方出来一些界面上的UI,如按钮的状态。 + * 在这个回调中,任务是获取不到文件大小,下载速度等参数 + */ + public void onPre(TASK task) { + + } + + /** + * 任务预加载完成 + */ + public void onTaskPre(TASK task) { + + } + + /** + * 任务恢复下载 + */ + public void onTaskResume(TASK task) { + + } + + /** + * 任务开始 + */ + public void onTaskStart(TASK task) { + + } + + /** + * 任务停止 + */ + public void onTaskStop(TASK task) { + + } + + /** + * 任务取消 + */ + public void onTaskCancel(TASK task) { + + } + + /** + * 任务失败 + * + * @deprecated {@link #onTaskFail(ITask, Exception)} + */ + public void onTaskFail(TASK task) { + + } + + /** + * 任务失败 + */ + public void onTaskFail(TASK task, Exception e) { + + } + + /** + * 任务完成 + */ + public void onTaskComplete(TASK task) { + + } + + /** + * 任务执行中 + */ + public void onTaskRunning(TASK task) { + + } + + public void onNoSupportBreakPoint(TASK task) { + + } + + @Override public void setListener(Object obj) { + + } +} \ No newline at end of file diff --git a/Aria/src/main/java/com/arialyy/aria/core/scheduler/AbsSchedulerListener.java b/Aria/src/main/java/com/arialyy/aria/core/scheduler/SubTaskListener.java similarity index 63% rename from Aria/src/main/java/com/arialyy/aria/core/scheduler/AbsSchedulerListener.java rename to Aria/src/main/java/com/arialyy/aria/core/scheduler/SubTaskListener.java index decb5ba6..d29fea62 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/scheduler/AbsSchedulerListener.java +++ b/Aria/src/main/java/com/arialyy/aria/core/scheduler/SubTaskListener.java @@ -19,63 +19,16 @@ import com.arialyy.aria.core.inf.AbsNormalEntity; import com.arialyy.aria.core.inf.ITask; /** - * Created by Aria.Lao on 2017/6/7. + * Created by Aria.Lao on 2019/6/26. + * 子任务事件回调类 */ -public class AbsSchedulerListener - implements ISchedulerListener { - - @Override public void onWait(TASK task) { - - } - - @Override public void onPre(TASK task) { - - } - - @Override public void onTaskPre(TASK task) { - - } - - @Override public void onTaskResume(TASK task) { - - } - - @Override public void onTaskStart(TASK task) { - - } - - @Override public void onTaskStop(TASK task) { - - } - - @Override public void onTaskCancel(TASK task) { - - } - - @Override public void onTaskFail(TASK task) { - - } - - @Override public void onTaskFail(TASK task, Exception e) { - - } - - @Override public void onTaskComplete(TASK task) { - - } - - @Override public void onTaskRunning(TASK task) { - - } +public class SubTaskListener + implements ISchedulerListener { public void onNoSupportBreakPoint(TASK task) { } - public void setListener(Object obj) { - - } - public void onSubTaskPre(TASK task, SUB_ENTITY subTask) { } @@ -108,4 +61,8 @@ public class AbsSchedulerListener keys = am.getReceiver().keySet(); for (String key : keys) { am.getReceiver().remove(key); @@ -207,7 +208,7 @@ public class UploadReceiver extends AbsReceiver { if (set != null && !set.isEmpty()) { for (Integer type : set) { if (type == ProxyHelper.PROXY_TYPE_UPLOAD) { - UploadSchedulers.getInstance().register(obj); + UploadSchedulers.getInstance().register(obj, TaskEnum.UPLOAD); } } } else { diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpThreadTask.java b/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpThreadTask.java index 85e91d51..15890a06 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpThreadTask.java +++ b/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpThreadTask.java @@ -23,8 +23,8 @@ import com.arialyy.aria.core.common.SubThreadConfig; import com.arialyy.aria.core.common.ftp.AbsFtpThreadTask; import com.arialyy.aria.core.common.ftp.FtpTaskConfig; import com.arialyy.aria.core.config.UploadConfig; -import com.arialyy.aria.core.upload.UploadEntity; import com.arialyy.aria.core.upload.UTaskWrapper; +import com.arialyy.aria.core.upload.UploadEntity; import com.arialyy.aria.exception.AriaIOException; import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.BufferedRandomAccessFile; @@ -107,6 +107,7 @@ class FtpThreadTask extends AbsFtpThreadTask { } catch (IOException e) { e.printStackTrace(); } + onThreadComplete(); } return this; } diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/HttpThreadTask.java b/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/HttpThreadTask.java index 8196d06e..913793ab 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/HttpThreadTask.java +++ b/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/HttpThreadTask.java @@ -102,6 +102,8 @@ class HttpThreadTask extends AbsThreadTask { fail(new TaskException(TAG, String.format("上传失败,filePath: %s, url: %s", getEntity().getFilePath(), getEntity().getUrl()), e)); + } finally { + onThreadComplete(); } return this; } diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/SimpleUploadUtil.java b/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/SimpleUploadUtil.java index 984a042a..51a56135 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/SimpleUploadUtil.java +++ b/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/SimpleUploadUtil.java @@ -65,7 +65,7 @@ public class SimpleUploadUtil implements IUtil, Runnable { } @Override public void onFail(AbsEntity entity, BaseException e, boolean needRetry) { - mListener.onFail(needRetry, e); + failUpload(e, needRetry); } }); new Thread(infoThread).start(); @@ -76,6 +76,14 @@ public class SimpleUploadUtil implements IUtil, Runnable { } } + private void failUpload(BaseException e, boolean needRetry) { + if (isStop || isCancel) { + return; + } + mListener.onFail(needRetry, e); + mUploader.onDestroy(); + } + @Override public String getKey() { return mTaskWrapper.getKey(); } @@ -108,8 +116,4 @@ public class SimpleUploadUtil implements IUtil, Runnable { } new Thread(this).start(); } - - @Override public void setMaxSpeed(int speed) { - mUploader.setMaxSpeed(speed); - } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/Uploader.java b/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/Uploader.java index 3770d30e..396280be 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/Uploader.java +++ b/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/Uploader.java @@ -19,6 +19,8 @@ import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.common.AbsThreadTask; import com.arialyy.aria.core.common.NormalFileer; import com.arialyy.aria.core.common.SubThreadConfig; +import com.arialyy.aria.core.event.Event; +import com.arialyy.aria.core.event.SpeedEvent; import com.arialyy.aria.core.inf.AbsTaskWrapper; import com.arialyy.aria.core.inf.IUploadListener; import com.arialyy.aria.core.upload.UTaskWrapper; @@ -51,4 +53,9 @@ class Uploader extends NormalFileer { } return null; } + + @Event + public void setMaxSpeed(SpeedEvent event) { + setMaxSpeed(event.speed); + } } diff --git a/Aria/src/main/java/com/arialyy/aria/orm/DBConfig.java b/Aria/src/main/java/com/arialyy/aria/orm/DBConfig.java index 3b22df9f..cedd69d8 100644 --- a/Aria/src/main/java/com/arialyy/aria/orm/DBConfig.java +++ b/Aria/src/main/java/com/arialyy/aria/orm/DBConfig.java @@ -22,6 +22,7 @@ import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.download.DownloadGroupEntity; import com.arialyy.aria.core.download.DGTaskWrapper; import com.arialyy.aria.core.download.DTaskWrapper; +import com.arialyy.aria.core.download.m3u8.M3U8Entity; import com.arialyy.aria.core.upload.UploadEntity; import com.arialyy.aria.core.upload.UTaskWrapper; import java.util.HashMap; @@ -37,7 +38,7 @@ class DBConfig { static boolean DEBUG = false; static Map mapping = new LinkedHashMap<>(); static String DB_NAME; - static int VERSION = 49; + static int VERSION = 51; /** * 是否将数据库保存在Sd卡,{@code true} 是 @@ -59,5 +60,6 @@ class DBConfig { mapping.put("UploadEntity", UploadEntity.class); mapping.put("ThreadRecord", ThreadRecord.class); mapping.put("TaskRecord", TaskRecord.class); + mapping.put("M3U8Entity", M3U8Entity.class); } } 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 29c6bd27..0a3d8519 100644 --- a/Aria/src/main/java/com/arialyy/aria/orm/SqlHelper.java +++ b/Aria/src/main/java/com/arialyy/aria/orm/SqlHelper.java @@ -98,7 +98,7 @@ final class SqlHelper extends SQLiteOpenHelper { handle314AriaUpdate(db); } else if (oldVersion < 45) { handle360AriaUpdate(db); - } else if (oldVersion < 49) { + } else if (oldVersion < 51) { handle365Update(db); } else { handleDbUpdate(db, null, null); @@ -223,6 +223,8 @@ final class SqlHelper extends SQLiteOpenHelper { } //删除中介表 mDelegate.dropTable(db, tableName + "_temp"); + }else { + mDelegate.createTable(db, clazz); } } db.setTransactionSuccessful(); 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 9dd486e3..0e681d7c 100644 --- a/Aria/src/main/java/com/arialyy/aria/util/BufferedRandomAccessFile.java +++ b/Aria/src/main/java/com/arialyy/aria/util/BufferedRandomAccessFile.java @@ -64,7 +64,7 @@ public final class BufferedRandomAccessFile extends RandomAccessFile { * c(f) the abstract contents of the file disk(f) the contents of f's * backing disk file closed(f) true iff the file is closed * - * "curr(f)" is an index in the closed interval [0, len(f)]. "c(f)" is a + * "curr(f)" is an peerIndex in the closed interval [0, len(f)]. "c(f)" is a * character sequence of length "len(f)". "c(f)" and "disk(f)" may differ if * "c(f)" contains unflushed writes not reflected in "disk(f)". The flush * operation has the effect of making "disk(f)" identical to "c(f)". 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 22797745..35482002 100644 --- a/Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java +++ b/Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java @@ -26,11 +26,11 @@ import android.text.TextUtils; import android.util.Base64; import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.FtpUrlEntity; +import com.arialyy.aria.core.command.AbsGroupCmd; +import com.arialyy.aria.core.command.AbsNormalCmd; +import com.arialyy.aria.core.command.GroupCmdFactory; import com.arialyy.aria.core.command.ICmd; -import com.arialyy.aria.core.command.group.AbsGroupCmd; -import com.arialyy.aria.core.command.group.GroupCmdFactory; -import com.arialyy.aria.core.command.normal.AbsNormalCmd; -import com.arialyy.aria.core.command.normal.NormalCmdFactory; +import com.arialyy.aria.core.command.NormalCmdFactory; import com.arialyy.aria.core.inf.AbsGroupTaskWrapper; import com.arialyy.aria.core.inf.AbsTaskWrapper; import dalvik.system.DexFile; @@ -70,6 +70,22 @@ import java.util.regex.Pattern; public class CommonUtil { private static final String TAG = "CommonUtil"; public static final String SERVER_CHARSET = "ISO-8859-1"; + private static long lastClickTime; + + /** + * 是否是快速点击,500ms内快速点击无效 + * + * @return true 快速点击 + */ + public static boolean isFastDoubleClick() { + long time = System.currentTimeMillis(); + long timeD = time - lastClickTime; + if (0 < timeD && timeD < 500) { + return true; + } + lastClickTime = time; + return false; + } /** * 将字符串转换为Ftp服务器默认的ISO-8859-1编码 @@ -83,8 +99,6 @@ public class CommonUtil { return new String(str.getBytes(charSet), SERVER_CHARSET); } - - /** * 删除文件 * @@ -968,7 +982,7 @@ public class CommonUtil { } try { if (file.createNewFile()) { - ALog.d(TAG, "创建文件成功:" + file.getAbsolutePath()); + //ALog.d(TAG, "创建文件成功:" + file.getAbsolutePath()); return true; } } catch (IOException e) { diff --git a/Aria/src/main/java/com/arialyy/aria/util/RecordUtil.java b/Aria/src/main/java/com/arialyy/aria/util/RecordUtil.java index 289414c8..1dcb8964 100644 --- a/Aria/src/main/java/com/arialyy/aria/util/RecordUtil.java +++ b/Aria/src/main/java/com/arialyy/aria/util/RecordUtil.java @@ -22,13 +22,11 @@ import com.arialyy.aria.core.common.TaskRecord; import com.arialyy.aria.core.common.ThreadRecord; import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.download.DownloadGroupEntity; -import com.arialyy.aria.core.download.m3u8.BaseM3U8Loader; import com.arialyy.aria.core.inf.AbsEntity; import com.arialyy.aria.core.inf.AbsNormalEntity; import com.arialyy.aria.core.upload.UploadEntity; import com.arialyy.aria.orm.DbEntity; import java.io.File; -import java.util.ArrayList; import java.util.List; /** @@ -154,7 +152,7 @@ public class RecordUtil { if (!targetFile.isDirectory()) { cacheDir = targetFile.getParent() + "/." + targetFile.getName(); } - removeTsCache(record, cacheDir); + removeTsCache(cacheDir); } else if (record.isBlock) { // 删除分块文件 removeBlockFile(record); } @@ -216,7 +214,7 @@ public class RecordUtil { cacheDir = String.format("%s/.%s_%s", targetFile.getParent(), targetFile.getName(), record.bandWidth); } - removeTsCache(record, cacheDir); + removeTsCache(cacheDir); } else if (record.isBlock) { // 删除分块文件 removeBlockFile(record); } @@ -289,15 +287,12 @@ public class RecordUtil { /** * 删除ts文件 */ - private static void removeTsCache(TaskRecord record, String cacheDir) { + private static void removeTsCache(String cacheDir) { if (!TextUtils.isEmpty(cacheDir)) { - List partPath = new ArrayList<>(); - for (ThreadRecord tr : record.threadRecords) { - partPath.add(BaseM3U8Loader.getTsFilePath(cacheDir, tr.threadId)); - } - for (String pp : partPath) { - File f = new File(pp); + + File[] files = new File(cacheDir).listFiles(); + for (File f : files) { if (f.exists()) { f.delete(); } diff --git a/AriaAnnotations/src/main/java/com/arialyy/annotations/Download.java b/AriaAnnotations/src/main/java/com/arialyy/annotations/Download.java index 83084ed9..2e540cad 100644 --- a/AriaAnnotations/src/main/java/com/arialyy/annotations/Download.java +++ b/AriaAnnotations/src/main/java/com/arialyy/annotations/Download.java @@ -31,8 +31,6 @@ import java.lang.annotation.Target; * } * * - * {@literal @}Download.onPre("http://www.baidu.com"),如果你的注解中增加了url描述, - * 则表示,所有下载任务中,只有下载地址为"http://www.baidu.com"的任务才能回调该注解的方法。 */ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface Download { diff --git a/AriaAnnotations/src/main/java/com/arialyy/annotations/DownloadGroup.java b/AriaAnnotations/src/main/java/com/arialyy/annotations/DownloadGroup.java index e98c1d14..8fe70a94 100644 --- a/AriaAnnotations/src/main/java/com/arialyy/annotations/DownloadGroup.java +++ b/AriaAnnotations/src/main/java/com/arialyy/annotations/DownloadGroup.java @@ -30,9 +30,6 @@ import java.lang.annotation.Target; * } * * - * {@literal @}Download.onPre("mGroupHash"),如果你的注解中增加了url描述, - * 则表示,所有下载任务中,只有下载地址为"myGroupHash"的任务才能回调该注解的方法。 - * * * 如果希望获取子任务的状态,可以使用onSub..类的注解 *
diff --git a/AriaAnnotations/src/main/java/com/arialyy/annotations/M3U8.java b/AriaAnnotations/src/main/java/com/arialyy/annotations/M3U8.java
new file mode 100644
index 00000000..f4b5e6b3
--- /dev/null
+++ b/AriaAnnotations/src/main/java/com/arialyy/annotations/M3U8.java
@@ -0,0 +1,57 @@
+/*
+ * 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.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Created by lyy on 2019/6/25.
+ * M3U8 切片事件
+ * 
+ *   
+ *      {@literal @}M3U8.onPeerStart
+ *       protected void onPeerStart(String m3u8Url, String peerPath, int peerIndex) {
+ *          ...
+ *       }
+ *   
+ * 
+ */ +@Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface M3U8 { + + /** + * "@M3U8.onPeerStart"注解,切片开始下载 + */ + @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onPeerStart { + String[] value() default { AriaConstance.NO_URL }; + } + + /** + * "@M3U8.onPeerFail注解,切片下载失败 + */ + @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onPeerFail { + String[] value() default { AriaConstance.NO_URL }; + } + + /** + * "@M3U8.onPeersComplete"注解,切片下载完成 + */ + @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onPeerComplete { + String[] value() default { AriaConstance.NO_URL }; + } +} diff --git a/AriaAnnotations/src/main/java/com/arialyy/annotations/TaskEnum.java b/AriaAnnotations/src/main/java/com/arialyy/annotations/TaskEnum.java new file mode 100644 index 00000000..5723fad1 --- /dev/null +++ b/AriaAnnotations/src/main/java/com/arialyy/annotations/TaskEnum.java @@ -0,0 +1,48 @@ +/* + * 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.annotations; + +/** + * Created by lyy on 2017/7/10. + * 任务类型枚举 + */ +public enum TaskEnum { + DOWNLOAD("com.arialyy.aria.core.download", "DownloadTask", "$$DownloadListenerProxy", + "NormalTaskListener"), + DOWNLOAD_GROUP("com.arialyy.aria.core.download", "DownloadGroupTask", + "$$DownloadGroupListenerProxy", "NormalTaskListener"), + DOWNLOAD_GROUP_SUB("com.arialyy.aria.core.download", "DownloadGroupTask", + "$$DGSubListenerProxy", "SubTaskListener"), + UPLOAD("com.arialyy.aria.core.upload", "UploadTask", "$$UploadListenerProxy", + "NormalTaskListener"), + M3U8_PEER("com.arialyy.aria.core.download", "DownloadTask", "$$M3U8PeerListenerProxy", + "M3U8PeerTaskListener"); + + public String pkg, className, proxySuffix, proxySuperClass; + + /** + * @param pkg 包名 + * @param className 对应到任务类名 + * @param proxySuffix 事件代理后缀 + * @param proxySuperClass 代理类的父类 + */ + TaskEnum(String pkg, String className, String proxySuffix, String proxySuperClass) { + this.pkg = pkg; + this.className = className; + this.proxySuffix = proxySuffix; + this.proxySuperClass = proxySuperClass; + } +} diff --git a/AriaAnnotations/src/main/java/com/arialyy/annotations/Upload.java b/AriaAnnotations/src/main/java/com/arialyy/annotations/Upload.java index dcaede22..ec0d842e 100644 --- a/AriaAnnotations/src/main/java/com/arialyy/annotations/Upload.java +++ b/AriaAnnotations/src/main/java/com/arialyy/annotations/Upload.java @@ -31,8 +31,6 @@ import java.lang.annotation.Target; * } * *
- * {@literal @}Upload.onPre("/mnt/sdcard/test.zip"),如果你的注解中增加了path描述, - * 则表示,所有上传任务中,只有上传路径为"/mnt/sdcard/test.zip"的任务才能回调该注解的方法。 */ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface Upload { diff --git a/AriaCompiler/src/main/java/com/arialyy/compiler/AriaProcessor.java b/AriaCompiler/src/main/java/com/arialyy/compiler/AriaProcessor.java index 33b9bb25..c7035ef3 100644 --- a/AriaCompiler/src/main/java/com/arialyy/compiler/AriaProcessor.java +++ b/AriaCompiler/src/main/java/com/arialyy/compiler/AriaProcessor.java @@ -17,6 +17,7 @@ package com.arialyy.compiler; import com.arialyy.annotations.Download; import com.arialyy.annotations.DownloadGroup; +import com.arialyy.annotations.M3U8; import com.arialyy.annotations.Upload; import com.google.auto.service.AutoService; import java.util.LinkedHashSet; @@ -85,6 +86,10 @@ import javax.lang.model.element.TypeElement; annotataions.add(Upload.onTaskRunning.class.getCanonicalName()); annotataions.add(Upload.onTaskStart.class.getCanonicalName()); annotataions.add(Upload.onTaskStop.class.getCanonicalName()); + // M3U8切片事件 + annotataions.add(M3U8.onPeerStart.class.getCanonicalName()); + annotataions.add(M3U8.onPeerComplete.class.getCanonicalName()); + annotataions.add(M3U8.onPeerFail.class.getCanonicalName()); return annotataions; } @@ -99,6 +104,7 @@ import javax.lang.model.element.TypeElement; mHandler.handleDownloadGroup(roundEnv); mHandler.handleDownloadGroupSub(roundEnv); mHandler.handleUpload(roundEnv); + mHandler.handleM3U8(roundEnv); mHandler.createProxyFile(); return true; } diff --git a/AriaCompiler/src/main/java/com/arialyy/compiler/CountFiler.java b/AriaCompiler/src/main/java/com/arialyy/compiler/CountFiler.java deleted file mode 100644 index 3783e222..00000000 --- a/AriaCompiler/src/main/java/com/arialyy/compiler/CountFiler.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.arialyy.compiler; - -import com.squareup.javapoet.ClassName; -import com.squareup.javapoet.CodeBlock; -import com.squareup.javapoet.FieldSpec; -import com.squareup.javapoet.JavaFile; -import com.squareup.javapoet.MethodSpec; -import com.squareup.javapoet.ParameterizedTypeName; -import com.squareup.javapoet.TypeSpec; -import java.io.IOException; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import javax.annotation.processing.Filer; -import javax.lang.model.element.Modifier; - -/** - * Created by lyy on 2017/9/6. - * 各类注解统计技术类 - */ -@Deprecated final class CountFiler { - private Filer mFiler; - private ParamObtainUtil mPbUtil; - - CountFiler(Filer filer, ParamObtainUtil pbUtil) { - mFiler = filer; - mPbUtil = pbUtil; - } - - /** - * 每一种注解对应的统计类 - */ - void createCountFile() throws IOException { - Set keys = mPbUtil.getListenerClass().keySet(); - if (keys.size() == 0) return; - TypeSpec.Builder builder = TypeSpec.classBuilder( - ProxyConstance.PROXY_COUNTER_NAME + UUID.randomUUID().toString().replace("-", "")) - .addModifiers(Modifier.PUBLIC, Modifier.FINAL); - - FieldSpec mappingField = FieldSpec.builder( - ParameterizedTypeName.get(ClassName.get(Map.class), ClassName.get(String.class), - ParameterizedTypeName.get(ClassName.get(Set.class), ClassName.get(String.class))), - ProxyConstance.PROXY_COUNTER_MAP) - .addModifiers(Modifier.PRIVATE) - .initializer("new $T()", HashMap.class) - .build(); - builder.addField(mappingField); - - //增加构造函数 - CodeBlock.Builder cb = CodeBlock.builder(); - cb.add("Set set = null;\n"); - for (String key : keys) { - addTypeData(key, mPbUtil.getListenerClass().get(key), cb); - } - MethodSpec structure = - MethodSpec.constructorBuilder().addModifiers(Modifier.PUBLIC).addCode(cb.build()).build(); - builder.addMethod(structure); - - builder.addMethod( - createMethod(ProxyConstance.COUNT_METHOD_DOWNLOAD, ProxyConstance.COUNT_DOWNLOAD)); - builder.addMethod( - createMethod(ProxyConstance.COUNT_METHOD_UPLOAD, ProxyConstance.COUNT_UPLOAD)); - builder.addMethod(createMethod(ProxyConstance.COUNT_METHOD_DOWNLOAD_GROUP, - ProxyConstance.COUNT_DOWNLOAD_GROUP)); - builder.addMethod(createMethod(ProxyConstance.COUNT_METHOD_DOWNLOAD_GROUP_SUB, - ProxyConstance.COUNT_DOWNLOAD_GROUP_SUB)); - - JavaFile jf = JavaFile.builder(ProxyConstance.PROXY_COUNTER_PACKAGE, builder.build()).build(); - createFile(jf); - } - - /** - * 创建不同任务类型的代理类集合 - * - * @param key {@link ParamObtainUtil#addListenerMapping(String, String)} - */ - private MethodSpec createMethod(String methodName, String key) { - MethodSpec.Builder builder = MethodSpec.methodBuilder(methodName); - ParameterizedTypeName returnName = - ParameterizedTypeName.get(ClassName.get(Set.class), ClassName.get(String.class)); - builder.addModifiers(Modifier.PUBLIC, Modifier.FINAL) - .returns(returnName) - .addCode("return " + ProxyConstance.PROXY_COUNTER_MAP + ".get(\"" + key + "\");\n"); - return builder.build(); - } - - /** - * 添加每一种注解对应类 - * - * @param type {@link ParamObtainUtil#addListenerMapping(String, String)} - */ - private void addTypeData(String type, Set clsNames, CodeBlock.Builder cb) { - if (clsNames == null || clsNames.isEmpty()) return; - StringBuilder sb = new StringBuilder(); - sb.append("set = new $T();\n"); - for (String clsName : clsNames) { - sb.append("set.add(\"").append(clsName).append("\");\n"); - } - sb.append("typeMapping.put(\"").append(type).append("\", ").append("set);\n"); - cb.add(sb.toString(), ClassName.get(HashSet.class)); - } - - private void createFile(JavaFile jf) throws IOException { - //jf.writeTo(System.out); - if (ProxyConstance.DEBUG) { - // 如果需要在控制台打印生成的文件,则去掉下面的注释 - jf.writeTo(System.out); - } else { - jf.writeTo(mFiler); - } - } -} diff --git a/AriaCompiler/src/main/java/com/arialyy/compiler/ElementHandler.java b/AriaCompiler/src/main/java/com/arialyy/compiler/ElementHandler.java index 9d92dd12..9ee86f0c 100644 --- a/AriaCompiler/src/main/java/com/arialyy/compiler/ElementHandler.java +++ b/AriaCompiler/src/main/java/com/arialyy/compiler/ElementHandler.java @@ -17,6 +17,8 @@ package com.arialyy.compiler; import com.arialyy.annotations.Download; import com.arialyy.annotations.DownloadGroup; +import com.arialyy.annotations.M3U8; +import com.arialyy.annotations.TaskEnum; import com.arialyy.annotations.Upload; import java.io.IOException; import javax.annotation.processing.Filer; @@ -113,7 +115,7 @@ class ElementHandler { } /** - * 处理搜索到的上传注解F + * 处理搜索到的上传注解 */ void handleUpload(RoundEnvironment roundEnv) { mPbUtil.saveMethod(TaskEnum.UPLOAD, roundEnv, Upload.onWait.class, ProxyConstance.WAIT); @@ -136,6 +138,18 @@ class ElementHandler { ProxyConstance.TASK_STOP); } + /** + * 处理搜索到到m3u8切片注解 + */ + void handleM3U8(RoundEnvironment roundEnv) { + mPbUtil.saveMethod(TaskEnum.M3U8_PEER, roundEnv, M3U8.onPeerStart.class, + ProxyConstance.TASK_START); + mPbUtil.saveMethod(TaskEnum.M3U8_PEER, roundEnv, M3U8.onPeerComplete.class, + ProxyConstance.TASK_COMPLETE); + mPbUtil.saveMethod(TaskEnum.M3U8_PEER, roundEnv, M3U8.onPeerFail.class, + ProxyConstance.TASK_FAIL); + } + /** * 在build文件夹中生成代理文件 */ @@ -150,6 +164,5 @@ class ElementHandler { void clean() { mPbUtil.getMethodParams().clear(); - mPbUtil.getListenerClass().clear(); } } diff --git a/AriaCompiler/src/main/java/com/arialyy/compiler/EntityInfo.java b/AriaCompiler/src/main/java/com/arialyy/compiler/EntityInfo.java new file mode 100644 index 00000000..27f35ced --- /dev/null +++ b/AriaCompiler/src/main/java/com/arialyy/compiler/EntityInfo.java @@ -0,0 +1,44 @@ +/* + * 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.compiler; + +/** + * Created by lyy on 2019/6/25. + * 实体信息 + */ +enum EntityInfo { + NORMAL("com.arialyy.aria.core.inf", "AbsNormalEntity"), + DOWNLOAD("com.arialyy.aria.core.download", "DownloadEntity"), + UPLOAD("com.arialyy.aria.core.upload", "UploadEntity"); + String pkg, className; + + public String getClassName() { + return className; + } + + public String getPkg() { + return pkg; + } + + /** + * @param pkg 包名 + * @param className 对应到任务类名 + */ + EntityInfo(String pkg, String className) { + this.pkg = pkg; + this.className = className; + } +} diff --git a/AriaCompiler/src/main/java/com/arialyy/compiler/EventProxyFiler.java b/AriaCompiler/src/main/java/com/arialyy/compiler/EventProxyFiler.java index c5b7ea4e..1b5589c6 100644 --- a/AriaCompiler/src/main/java/com/arialyy/compiler/EventProxyFiler.java +++ b/AriaCompiler/src/main/java/com/arialyy/compiler/EventProxyFiler.java @@ -17,9 +17,10 @@ package com.arialyy.compiler; import com.arialyy.annotations.Download; import com.arialyy.annotations.DownloadGroup; +import com.arialyy.annotations.M3U8; +import com.arialyy.annotations.TaskEnum; import com.arialyy.annotations.Upload; import com.squareup.javapoet.ClassName; -import com.squareup.javapoet.CodeBlock; import com.squareup.javapoet.FieldSpec; import com.squareup.javapoet.JavaFile; import com.squareup.javapoet.MethodSpec; @@ -28,8 +29,6 @@ import com.squareup.javapoet.ParameterizedTypeName; import com.squareup.javapoet.TypeSpec; import java.io.IOException; import java.lang.annotation.Annotation; -import java.util.HashMap; -import java.util.HashSet; import java.util.Map; import java.util.Set; import javax.annotation.processing.Filer; @@ -87,18 +86,39 @@ final class EventProxyFiler { } /** - * 创建代理方法 + * 创建M3u8切片的代理方法 * * @param taskEnum 任务类型枚举{@link TaskEnum} - * @param annotation {@link Download}、{@link Upload} + * @param annotation {@link Download}、{@link Upload}、{@link M3U8} * @param methodInfo 被代理类注解的方法信息 */ - private MethodSpec createProxyMethod(TaskEnum taskEnum, Class annotation, + private MethodSpec createM3U8PeerMethod(TaskEnum taskEnum, Class annotation, MethodInfo methodInfo) { - ClassName task = ClassName.get(taskEnum.getPkg(), taskEnum.getClassName()); - ParameterSpec taskParam = - ParameterSpec.builder(task, "task").addModifiers(Modifier.FINAL).build(); + String sb = String.format("obj.%s(m3u8Url, peerPath, peerIndex);\n", methodInfo.methodName); + + MethodSpec.Builder builder = MethodSpec.methodBuilder(annotation.getSimpleName()) + .addModifiers(Modifier.PUBLIC) + .returns(void.class) + .addParameter(String.class, "m3u8Url", Modifier.FINAL) + .addParameter(String.class, "peerPath", Modifier.FINAL) + .addParameter(int.class, "peerIndex", Modifier.FINAL) + .addAnnotation(Override.class) + .addCode(sb); + + return builder.build(); + } + + /** + * 创建任务的代理方法 + * + * @param taskEnum 任务类型枚举{@link TaskEnum} + * @param annotation {@link Download}、{@link Upload} + * @param methodInfo 被代理类注解的方法信息 + */ + private MethodSpec createTaskMethod(TaskEnum taskEnum, Class annotation, + MethodInfo methodInfo) { + ClassName task = ClassName.get(taskEnum.pkg, taskEnum.className); String callCode; @@ -125,26 +145,23 @@ final class EventProxyFiler { callCode = "task"; } } - StringBuilder sb = new StringBuilder(); - sb.append("obj.") - .append(methodInfo.methodName) - .append("((") - .append(taskEnum.getClassName()) - .append(")") - .append(callCode) - .append(");\n"); + String sb = String.format("obj.%s((%s)%s);\n", + methodInfo.methodName, taskEnum.className, callCode); + + ParameterSpec taskParam = + ParameterSpec.builder(task, "task").addModifiers(Modifier.FINAL).build(); MethodSpec.Builder builder = MethodSpec.methodBuilder(annotation.getSimpleName()) .addModifiers(Modifier.PUBLIC) .returns(void.class) .addParameter(taskParam) .addAnnotation(Override.class) - .addCode(sb.toString()); + .addCode(sb); //任务组接口 if (taskEnum == TaskEnum.DOWNLOAD_GROUP_SUB) { ClassName subTask = - ClassName.get(TaskEnum.DOWNLOAD_ENTITY.pkg, TaskEnum.DOWNLOAD_ENTITY.className); + ClassName.get(EntityInfo.DOWNLOAD.pkg, EntityInfo.DOWNLOAD.className); ParameterSpec subTaskParam = ParameterSpec.builder(subTask, "subEntity").addModifiers(Modifier.FINAL).build(); @@ -177,41 +194,22 @@ final class EventProxyFiler { //添加注解方法 for (TaskEnum te : entity.methods.keySet()) { Map, MethodInfo> methodInfoMap = entity.methods.get(te); - //if (entity.proxyClassName.contains(TaskEnum.DOWNLOAD.proxySuffix)) { - // type.add(1); - //} else if (entity.proxyClassName.contains(TaskEnum.DOWNLOAD_GROUP.proxySuffix)) { - // type.add(2); - //} else if (entity.proxyClassName.contains(TaskEnum.UPLOAD.proxySuffix)) { - // type.add(3); - //} else if (entity.proxyClassName.contains(TaskEnum.UPLOAD_GROUP.proxySuffix)) { - // type.add(4); - //} if (methodInfoMap != null) { for (Class annotation : methodInfoMap.keySet()) { - MethodSpec method = createProxyMethod(te, annotation, methodInfoMap.get(annotation)); - builder.addMethod(method); + if (te == TaskEnum.DOWNLOAD + || te == TaskEnum.DOWNLOAD_GROUP + || te == TaskEnum.DOWNLOAD_GROUP_SUB + || te == TaskEnum.UPLOAD) { + MethodSpec method = createTaskMethod(te, annotation, methodInfoMap.get(annotation)); + builder.addMethod(method); + } else if (te == TaskEnum.M3U8_PEER) { + MethodSpec method = createM3U8PeerMethod(te, annotation, methodInfoMap.get(annotation)); + builder.addMethod(method); + } } } } - //注册当前类 - //for (Integer i : type) { - // String str = null; - // switch (i) { - // case 1: - // case 2: - // str = "$T.download(obj).register();\n"; - // break; - // case 3: - // case 4: - // str = "$T.upload(obj).register();\n"; - // break; - // } - // if (str != null) { - // cb.add(str, ClassName.get("com.arialyy.aria.core", "Aria")); - // } - //} - MethodSpec structure = MethodSpec.constructorBuilder().addModifiers(Modifier.PUBLIC).build(); builder.addMethod(structure); @@ -228,16 +226,29 @@ final class EventProxyFiler { builder.addJavadoc("该文件为Aria自动生成的代理文件,请不要修改该文件的任何代码!\n"); //创建父类参数 - ClassName superClass = ClassName.get("com.arialyy.aria.core.scheduler", "AbsSchedulerListener"); - //主任务泛型参数 - ClassName taskTypeVariable = - ClassName.get(entity.mainTaskEnum.pkg, entity.mainTaskEnum.className); - //子任务泛型参数 - ClassName subTaskTypeVariable = - ClassName.get(entity.subTaskEnum.pkg, entity.subTaskEnum.className); - - builder.superclass( - ParameterizedTypeName.get(superClass, taskTypeVariable, subTaskTypeVariable)); + ClassName superClass = + ClassName.get("com.arialyy.aria.core.scheduler", entity.mainTaskEnum.proxySuperClass); + + if (entity.mainTaskEnum == TaskEnum.DOWNLOAD + || entity.mainTaskEnum == TaskEnum.UPLOAD + || entity.mainTaskEnum == TaskEnum.DOWNLOAD_GROUP) { + ClassName taskTypeVariable = + ClassName.get(entity.mainTaskEnum.pkg, entity.mainTaskEnum.className); + builder.superclass(ParameterizedTypeName.get(superClass, taskTypeVariable)); + } else if (entity.mainTaskEnum == TaskEnum.DOWNLOAD_GROUP_SUB) { + + ClassName taskTypeVariable = + ClassName.get(entity.mainTaskEnum.pkg, entity.mainTaskEnum.className); + //子任务泛型参数 + ClassName subTaskTypeVariable = + ClassName.get(entity.subTaskEnum.pkg, entity.subTaskEnum.className); + + builder.superclass( + ParameterizedTypeName.get(superClass, taskTypeVariable, subTaskTypeVariable)); + } else if (entity.mainTaskEnum == TaskEnum.M3U8_PEER) { + builder.superclass(superClass); + } + builder.addMethod(listener); return builder.build(); } diff --git a/AriaCompiler/src/main/java/com/arialyy/compiler/ParamObtainUtil.java b/AriaCompiler/src/main/java/com/arialyy/compiler/ParamObtainUtil.java index 422eb8e2..be2d3918 100644 --- a/AriaCompiler/src/main/java/com/arialyy/compiler/ParamObtainUtil.java +++ b/AriaCompiler/src/main/java/com/arialyy/compiler/ParamObtainUtil.java @@ -17,6 +17,7 @@ package com.arialyy.compiler; import com.arialyy.annotations.Download; import com.arialyy.annotations.DownloadGroup; +import com.arialyy.annotations.TaskEnum; import com.arialyy.annotations.Upload; import java.lang.annotation.Annotation; import java.util.Collections; @@ -41,20 +42,12 @@ import javax.lang.model.util.Elements; */ class ParamObtainUtil { private Map mMethodParams = new HashMap<>(); - private Map> mListenerClass = new HashMap<>(); private Elements mElementUtil; ParamObtainUtil(Elements elements) { mElementUtil = elements; } - /** - * 获取需要创建的代理类参数 - */ - Map> getListenerClass() { - return mListenerClass; - } - /** * 获取搜索到的代理方法参数 */ @@ -75,13 +68,17 @@ class ParamObtainUtil { PackageElement packageElement = mElementUtil.getPackageOf(classElement); String methodName = method.getSimpleName().toString(); - String className = method.getEnclosingElement().toString(); //全类名\ + String className = method.getEnclosingElement().toString(); //全类名 String key = className + taskEnum.proxySuffix; ProxyClassParam proxyEntity = mMethodParams.get(key); MethodInfo methodInfo = new MethodInfo(); methodInfo.methodName = methodName; methodInfo.params = (List) method.getParameters(); - checkMethod(taskEnum, method, annotationClazz, methodInfo.params); + if (taskEnum == TaskEnum.M3U8_PEER) { + checkM3U8PeerMethod(method, methodInfo.params); + } else { + checkTaskMethod(taskEnum, method, annotationClazz, methodInfo.params); + } if (proxyEntity == null) { proxyEntity = new ProxyClassParam(); @@ -91,7 +88,7 @@ class ParamObtainUtil { proxyEntity.proxyClassName = proxyEntity.className + taskEnum.proxySuffix; proxyEntity.mainTaskEnum = taskEnum; if (taskEnum == TaskEnum.DOWNLOAD_GROUP_SUB || taskEnum == TaskEnum.DOWNLOAD_GROUP) { - proxyEntity.subTaskEnum = TaskEnum.DOWNLOAD_ENTITY; + proxyEntity.subTaskEnum = EntityInfo.DOWNLOAD; } mMethodParams.put(key, proxyEntity); } @@ -110,49 +107,52 @@ class ParamObtainUtil { * 获取注解的内容 */ private Set getValues(TaskEnum taskEnum, ExecutableElement method, int annotationType) { - String clsName = method.getEnclosingElement().toString(); String[] keys = null; switch (taskEnum) { case DOWNLOAD: keys = ValuesUtil.getDownloadValues(method, annotationType); - addListenerMapping(clsName, ProxyConstance.COUNT_DOWNLOAD); break; case UPLOAD: keys = ValuesUtil.getUploadValues(method, annotationType); - addListenerMapping(clsName, ProxyConstance.COUNT_UPLOAD); break; case DOWNLOAD_GROUP: keys = ValuesUtil.getDownloadGroupValues(method, annotationType); - addListenerMapping(clsName, ProxyConstance.COUNT_DOWNLOAD_GROUP); break; case DOWNLOAD_GROUP_SUB: keys = ValuesUtil.getDownloadGroupSubValues(method, annotationType); - addListenerMapping(clsName, ProxyConstance.COUNT_DOWNLOAD_GROUP_SUB); + break; + case M3U8_PEER: + keys = ValuesUtil.getM3U8PeerValues(method, annotationType); break; } return keys == null ? null : convertSet(keys); } /** - * 添加方法映射 - * - * @param clsName 注解事件的类 - * @param key {@link ProxyConstance#COUNT_DOWNLOAD}、{@link ProxyConstance#COUNT_UPLOAD}、{@link - * ProxyConstance#COUNT_DOWNLOAD_GROUP}、{@link ProxyConstance#COUNT_DOWNLOAD_GROUP_SUB} + * 检查m3u8注解方法参数 */ - void addListenerMapping(String clsName, String key) { - Set cls = mListenerClass.get(key); - if (cls == null) { - cls = new HashSet<>(); - mListenerClass.put(key, cls); + private void checkM3U8PeerMethod(ExecutableElement method, List params) { + String methodName = method.getSimpleName().toString(); + String className = method.getEnclosingElement().toString(); + Set modifiers = method.getModifiers(); + if (modifiers.contains(Modifier.PRIVATE)) { + throw new IllegalAccessError(String.format("%s.%s, 不能为private方法", className, methodName)); + } + + if (params.size() != 3 + || !params.get(0).asType().toString().equals(String.class.getName()) + || !params.get(1).asType().toString().equals(String.class.getName()) + || !params.get(2).asType().toString().equals("int")) { + throw new IllegalArgumentException( + String.format("%s.%s 的参数错误,该方法需要的参数为:String, String, int", className, + methodName)); } - cls.add(clsName); } /** - * 检查和下载相关的方法,如果被注解的方法为private或参数不合法,则抛异常 + * 检查任务注解的相关参数,如果被注解的方法为private或参数不合法或参数错误,停止任务 */ - private void checkMethod(TaskEnum taskEnum, ExecutableElement method, + private void checkTaskMethod(TaskEnum taskEnum, ExecutableElement method, Class annotationClazz, List params) { String methodName = method.getSimpleName().toString(); String className = method.getEnclosingElement().toString(); @@ -162,7 +162,28 @@ class ParamObtainUtil { } if (taskEnum == TaskEnum.DOWNLOAD_GROUP_SUB) { if (isFailAnnotation(annotationClazz)) { - if (params.size() != 3 && params.size() != 2) { + if (params.size() < 2 || params.size() > 3) { + throw new IllegalArgumentException( + String.format("%s.%s参数错误, 参数只能是两个或三个,第一个参数是:%s,第二个参数是:%s,第三个参数(可选)是:%s", className, + methodName, + getCheckParams(taskEnum), getCheckSubParams(taskEnum), + Exception.class.getSimpleName())); + } + + if (params.size() == 2 + && (!params.get(0).asType().toString().equals(getCheckParams(taskEnum)) + || !params.get(1).asType().toString().equals(getCheckSubParams(taskEnum)))) { + throw new IllegalArgumentException( + String.format("%s.%s参数错误, 参数只能是两个或三个,第一个参数是:%s,第二个参数是:%s,第三个参数(可选)是:%s", className, + methodName, + getCheckParams(taskEnum), getCheckSubParams(taskEnum), + Exception.class.getSimpleName())); + } + + if (params.size() == 3 + && (!params.get(0).asType().toString().equals(getCheckParams(taskEnum)) + || !params.get(1).asType().toString().equals(getCheckSubParams(taskEnum)) + || !params.get(2).asType().toString().equals(Exception.class.getName()))) { throw new IllegalArgumentException( String.format("%s.%s参数错误, 参数只能是两个或三个,第一个参数是:%s,第二个参数是:%s,第三个参数(可选)是:%s", className, methodName, @@ -170,39 +191,46 @@ class ParamObtainUtil { Exception.class.getSimpleName())); } } else { - if (params.size() != 2) { + if (params.size() == 2 + && (!params.get(0).asType().toString().equals(getCheckParams(taskEnum)) + || !params.get(1).asType().toString().equals(getCheckSubParams(taskEnum)))) { throw new IllegalArgumentException( - String.format("%s.%s参数错误, 参数只能是两个,第一个参数是:%s,第二个参数是:%s", className, methodName, + String.format("%s.%s参数错误, 参数只能是两个或三个,第一个参数是:%s,第二个参数是:%s", className, + methodName, getCheckParams(taskEnum), getCheckSubParams(taskEnum))); } } } else { if (isFailAnnotation(annotationClazz)) { - if (params.size() != 1 && params.size() != 2) { + if (params.size() < 1 || params.size() > 2) { throw new IllegalArgumentException( - String.format("%s.%s参数错误, 参数只能有一个或两个,第一个参数是:%s,第二个参(可选)数是:%s", className, methodName, + String.format("%s.%s参数错误, 参数只能有一个或两个,第一个参数是:%s,第二个参数(可选)是:%s", className, methodName, + getCheckParams(taskEnum), Exception.class.getSimpleName())); + } + + if (params.size() == 1 + && (!params.get(0).asType().toString().equals(getCheckParams(taskEnum)))) { + throw new IllegalArgumentException( + String.format("%s.%s参数错误, 参数只能有一个或两个,第一个参数是:%s,第二个参数(可选)是:%s", className, methodName, + getCheckParams(taskEnum), Exception.class.getSimpleName())); + } + + if (params.size() == 2 + && (!params.get(0).asType().toString().equals(getCheckParams(taskEnum)) + || !params.get(1).asType().toString().equals(Exception.class.getName()))) { + throw new IllegalArgumentException( + String.format("%s.%s参数错误, 参数只能有一个或两个,第一个参数是:%s,第二个参数(可选)是:%s", className, methodName, getCheckParams(taskEnum), Exception.class.getSimpleName())); } } else { - if (params.size() != 1) { + if (params.size() != 1 + && !params.get(0).asType().toString().equals(getCheckParams(taskEnum))) { throw new IllegalArgumentException( String.format("%s.%s参数错误, 参数只能有一个,且参数必须是:%s", className, methodName, getCheckParams(taskEnum))); } } } - if (!params.get(0).asType().toString().equals(getCheckParams(taskEnum))) { - throw new IllegalArgumentException( - String.format("%s.%s参数【%s】类型错误,参数必须是:%s", className, methodName, - params.get(0).getSimpleName(), getCheckParams(taskEnum))); - } - if (taskEnum == TaskEnum.DOWNLOAD_GROUP_SUB) { - if (!params.get(1).asType().toString().equals(getCheckSubParams(taskEnum))) { - throw new IllegalArgumentException( - String.format("%s.%s参数【%s】类型错误,参数必须是:%s", className, methodName, - params.get(0).getSimpleName(), getCheckSubParams(taskEnum))); - } - } } /** @@ -241,7 +269,7 @@ class ParamObtainUtil { */ private String getCheckSubParams(TaskEnum taskEnum) { if (taskEnum == TaskEnum.DOWNLOAD_GROUP_SUB) { - return TaskEnum.DOWNLOAD_ENTITY.pkg + "." + TaskEnum.DOWNLOAD_ENTITY.className; + return EntityInfo.DOWNLOAD.pkg + "." + EntityInfo.DOWNLOAD.className; } return ""; } diff --git a/AriaCompiler/src/main/java/com/arialyy/compiler/ProxyClassParam.java b/AriaCompiler/src/main/java/com/arialyy/compiler/ProxyClassParam.java index b5f3f244..6e630a05 100644 --- a/AriaCompiler/src/main/java/com/arialyy/compiler/ProxyClassParam.java +++ b/AriaCompiler/src/main/java/com/arialyy/compiler/ProxyClassParam.java @@ -15,6 +15,7 @@ */ package com.arialyy.compiler; +import com.arialyy.annotations.TaskEnum; import java.lang.annotation.Annotation; import java.util.HashMap; import java.util.Map; @@ -44,7 +45,7 @@ class ProxyClassParam { /** * 子任务泛型参数 */ - TaskEnum subTaskEnum = TaskEnum.NORMAL_ENTITY; + EntityInfo subTaskEnum = EntityInfo.NORMAL; Set taskEnums; Map> keyMappings = new HashMap<>(); diff --git a/AriaCompiler/src/main/java/com/arialyy/compiler/ProxyConstance.java b/AriaCompiler/src/main/java/com/arialyy/compiler/ProxyConstance.java index 8ebb6978..88879f06 100644 --- a/AriaCompiler/src/main/java/com/arialyy/compiler/ProxyConstance.java +++ b/AriaCompiler/src/main/java/com/arialyy/compiler/ProxyConstance.java @@ -26,30 +26,6 @@ interface ProxyConstance { */ String SET_LISTENER = "setListener"; - /** - * 代理配置类 - */ - String PROXY_COUNTER_PACKAGE = "com.arialyy.aria"; - /** - * 代理分类统计 - */ - String PROXY_COUNTER_NAME = "ProxyClassCounter"; - - /** - * 代理分类统计映射表 - */ - String PROXY_COUNTER_MAP = "typeMapping"; - - String COUNT_DOWNLOAD = "download"; - String COUNT_DOWNLOAD_GROUP = "downloadGroup"; - String COUNT_DOWNLOAD_GROUP_SUB = "downloadGroupSub"; - String COUNT_UPLOAD = "upload"; - - String COUNT_METHOD_DOWNLOAD = "getDownloadCounter"; - String COUNT_METHOD_DOWNLOAD_GROUP = "getDownloadGroupCounter"; - String COUNT_METHOD_DOWNLOAD_GROUP_SUB = "getDownloadGroupSubCounter"; - String COUNT_METHOD_UPLOAD = "getUploadCounter"; - int WAIT = 0X10; int PRE = 0X11; int TASK_PRE = 0X12; diff --git a/AriaCompiler/src/main/java/com/arialyy/compiler/TaskEnum.java b/AriaCompiler/src/main/java/com/arialyy/compiler/TaskEnum.java deleted file mode 100644 index d5a65feb..00000000 --- a/AriaCompiler/src/main/java/com/arialyy/compiler/TaskEnum.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.arialyy.compiler; - -/** - * Created by lyy on 2017/7/10. - * 任务类型枚举 - */ -enum TaskEnum { - DOWNLOAD("com.arialyy.aria.core.download", "DownloadTask", - "$$DownloadListenerProxy"), DOWNLOAD_GROUP("com.arialyy.aria.core.download", - "DownloadGroupTask", "$$DownloadGroupListenerProxy"), DOWNLOAD_GROUP_SUB( - "com.arialyy.aria.core.download", "DownloadGroupTask", "$$DownloadGroupListenerProxy"), UPLOAD( - "com.arialyy.aria.core.upload", "UploadTask", "$$UploadListenerProxy"), UPLOAD_GROUP( - "com.arialyy.aria.core.upload", "UploadGroupTask", - "$$UploadGroupListenerProxy"), NORMAL_ENTITY("com.arialyy.aria.core.inf", "AbsNormalEntity", - ""), DOWNLOAD_ENTITY("com.arialyy.aria.core.download", "DownloadEntity", ""); - - String pkg, className, proxySuffix; - - public String getClassName() { - return className; - } - - public String getProxySuffix() { - return proxySuffix; - } - - public String getPkg() { - return pkg; - } - - /** - * @param pkg 包名 - * @param className 任务完整类名 - * @param proxySuffix 事件代理后缀 - */ - TaskEnum(String pkg, String className, String proxySuffix) { - this.pkg = pkg; - this.className = className; - this.proxySuffix = proxySuffix; - } -} diff --git a/AriaCompiler/src/main/java/com/arialyy/compiler/ValuesUtil.java b/AriaCompiler/src/main/java/com/arialyy/compiler/ValuesUtil.java index f9c23f1c..3adc0164 100644 --- a/AriaCompiler/src/main/java/com/arialyy/compiler/ValuesUtil.java +++ b/AriaCompiler/src/main/java/com/arialyy/compiler/ValuesUtil.java @@ -17,6 +17,7 @@ package com.arialyy.compiler; import com.arialyy.annotations.Download; import com.arialyy.annotations.DownloadGroup; +import com.arialyy.annotations.M3U8; import com.arialyy.annotations.Upload; import javax.lang.model.element.ExecutableElement; @@ -25,6 +26,26 @@ import javax.lang.model.element.ExecutableElement; * 获取注解value工具 */ final class ValuesUtil { + + /** + * 获取m3u8切片注解信息 + */ + static String[] getM3U8PeerValues(ExecutableElement method, int annotationType) { + String[] values = null; + switch (annotationType) { + case ProxyConstance.TASK_START: + values = method.getAnnotation(M3U8.onPeerStart.class).value(); + break; + case ProxyConstance.TASK_COMPLETE: + values = method.getAnnotation(M3U8.onPeerComplete.class).value(); + break; + case ProxyConstance.TASK_FAIL: + values = method.getAnnotation(M3U8.onPeerFail.class).value(); + break; + } + return values; + } + /** * 获取下载任务组子任务的的注解数据 */ diff --git a/DEV_LOG.md b/DEV_LOG.md index 56fd3b4e..f920fb9f 100644 --- a/DEV_LOG.md +++ b/DEV_LOG.md @@ -4,13 +4,15 @@ - 新增ftp上传拦截器 https://github.com/AriaLyy/Aria/issues/402 - 重构线程任务模块 - 修复一个低版本数据库升级的问题 https://github.com/AriaLyy/Aria/issues/407 - - 新增遵循m3u8协议的文件下载 + - 新增m3u8协议的文件下载 - 修复拦截器可能出现的空指针问题 - 移除`DownloadGroupEntity`字段`groupHash`的主键约束,`DownloadEntity`字段`groupHash`的外键约束,`TaskRecord`字段`dGroupHash`的外键约束 - 优化关联查询的性能 - 修复任务记录删除失败的问题 - 优化网络连接状态获取的逻辑 - 修复配置文件的某些配置失效的问题 + - 新增m3u8切片状态注解`@M3U8.onPeerStart`,`@M3U8.onPeerComplete`,`@M3U8.onPeerFail` + - 新增动态指定m3u8协议视频的下载功能(边下边播) + v_3.6.4 (2019/5/16) - 优化任务接收器的代码结构 - 修复`DbEntity.saveAll()`失败的问题 diff --git a/app/build.gradle b/app/build.gradle index ee2ab92a..96dc248b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,10 +16,22 @@ android { multiDexEnabled true vectorDrawables.useSupportLibrary = true } + + signingConfigs { + release { + storeFile file("lyy.keystore") + storePassword "123456" + keyAlias "key0" + keyPassword "123456" + v2SigningEnabled false + } + } + buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + signingConfig signingConfigs.release } } @@ -50,8 +62,8 @@ dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib:${rootProject.ext.kotlin_version}" api project(':Aria') kapt project(':AriaCompiler') -// api 'com.arialyy.aria:aria-core:3.6.4' -// kapt 'com.arialyy.aria:aria-compiler:3.6.4' + // api 'com.arialyy.aria:aria-core:3.6.4' + // kapt 'com.arialyy.aria:aria-compiler:3.6.4' // compile 'com.arialyy.aria:aria-core:3.3.14' // annotationProcessor 'com.arialyy.aria:aria-compiler:3.3.14' diff --git a/app/lyy.keystore b/app/lyy.keystore new file mode 100644 index 0000000000000000000000000000000000000000..60a3e436f8c63dd68ececfffd7e4e1f3a6fa0534 GIT binary patch literal 2170 zcmb`Hc{CJ^8pdaj(TqflGPX!r##qNzvL-Er!NsU7k$o*oW0)AxckN_LV`ME`LiRyq z`FzNdB}+_$L}VGJ8lUr>d(Y|qfB$&S`8|KV=Y8JyJe)Po8UO$Q9SZo5AfB$F*hAx) zvE8!-06;-lGK7Og!r*c+AOt82;sXMq009L*o41%H;i^D(guTC%eELiuu ziX!9bEz*Te*Bl`2{l_1gNS$pd5^ap`=dP_jW7ea)b^ErS-lCrIMr+ZPE{>J|8}17$ zd6{i(Hk+m_|5(g3~WhkAjibo&$i}#}YSgOokGU2R`xr_q_m0IhPot>6KNTRu=677-(+~-c;0W(bEz;AdjDuoZdjh#;~&5( zqxgQ-$nX+YcE-qZ%cU^?)~HNAuXAx5bwtK2N)UX{sRep(Cov0OU8dr~%lRLtUXW%`R z&@ks*+C`5bvS~#>cz;g2We1cv(I(wEYp1kj4;c1EqGckOxZTIi&GrI{>HJZAH?F!2 z7b8F)s^%9qy<71`)NaQa8aUF~xw}RA;$#Z)fqqVVXcsz3pxK)?v_tPBU{;T`G9TpK zt)2Yp0=dn9LF=t|sp1yHcaT;4(Z2N@H}l)8l-^W~U*VIETc@e)faJ=MDb%~$zROgB z^YcHA_T02TUcevdc1P8Pa*kiqiT8%cdpVLkDKcxFcCfr4#Q8D(!D<=ovoDh4Zn0!N zGbrqurb?W(Z4OwKk#m_?!HK=J0b z?0WS1w~1WW#-t1hUE=S8OWtz;2kWpqmY=pBrhRBEacDVuy2X;^3}x3p_=DP-I4cdFeFOV#i5#EdhwlJ zp1aU6FB5f2RR@1?0v`4_7QdqzbI!-C>DKzhi#iTx#e(X7=lNyoiXXcJj7rf9>eQBc zV7BPp;u!~9n4fVRoE(*Q9>rmZ^A_;nxC0aBNL?lIn8DXb<=}+}#?3t^N3@KW*g6?m7#n+&X2g1oq*}t#gc)v3{~~KpO?+$ZM0Hv~D6? z6mBcYZ_4`j%dzMhp9o_kxbBdlNJw(|w#D~Mjoc0Y!Lv%Cbzm(0hQ9`onu7b0#=9&y z5LQ7OR=aNR>$t2~6F+D^0wD^&Q14ydEHnRTqwnB0B-&!F$l2oAw@01mEUD=PgiO6R zlFz89x->%86&FmPkbh}}L|cZ`6_?{0ZRbRr2=u1vaj!iEQzuPll9QmL_fiA11FER9 z8(E7Cu&u}x(&wt$m?T+Czmn3cmE~!6ff-9EV%9RxoG1U&i%?sP8dehk0IOihU_~q$ zBt!*+fFKYA+GC@FMZmaaDJB#a0tn=R0TANtEkusAyiclE%rb5|2T;Zl>B{-!zdpC7@=9LLSl?u<6NV@mry-)<)!3Z`xmHOLs}8@g{Gx>e z7uH(hif3U6)L=mG#LYLyoXaxlI*M^1viNKo8eRpXzcf`=HK_|f3ncfu08aVuLB}IZ zrD9jtQWXmNnzLVLDV#o;)vkGKLxI$GN-T6#=(>SCiKOh;^HEp>vwX}N0}JHKSYaIq zg}M*ZUG2qVvLdcbKV4N}H!x;`&Hxr+11l>!&tSxN*>f;1+{EX=5J=Ot1gjQ(|AH3< ze#)QWaS7=j6?9hkM{_frL>@naetmCt)3DqfB`31E#^YuZh}IQ=h}^*Yg1|rkus{MU zhD9G<7L9}mLIikubp&7SXxV3Iov73LB%d1;n(;p&9{$2%h(Lf^*E89%ZWJ%%DAI|`ho8VM>@LY5#0y?1)^@F~ht9%oMkgxe@_?bxtXfs zDs@zU4;Bz>02kBRcgrY$O5zn{GQx~BRgQb0ZC=;?oJJzh@yy^oX$#r_ F|KE3E!L$GX literal 0 HcmV?d00001 diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 646511c1..96cccb3f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -12,6 +12,7 @@ android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" + android:networkSecurityConfig="@xml/network_security_config" android:supportsRtl="true" android:theme="@style/AppTheme.NoActionBar" tools:ignore="GoogleAppIndexingWarning"> @@ -47,8 +48,8 @@ android:screenOrientation="landscape" android:theme="@style/FullScreen" android:windowSoftInputMode="stateHidden|adjustResize"/> - - + + diff --git a/app/src/main/assets/help_code/KotlinHttpDownload.kt b/app/src/main/assets/help_code/KotlinHttpDownload.kt index 88892ffb..0d9cc041 100644 --- a/app/src/main/assets/help_code/KotlinHttpDownload.kt +++ b/app/src/main/assets/help_code/KotlinHttpDownload.kt @@ -68,7 +68,7 @@ class KotlinDownloadActivity : BaseActivity() { } /** - * 注解方法不能添加internal修饰符,否则会出现e: [kapt] An exception occurred: java.lang.IllegalArgumentException: index 1 for '$a' not in range (received 0 arguments)错误 + * 注解方法不能添加internal修饰符,否则会出现e: [kapt] An exception occurred: java.lang.IllegalArgumentException: peerIndex 1 for '$a' not in range (received 0 arguments)错误 */ @Download.onTaskRunning fun running(task: DownloadTask) { diff --git a/app/src/main/java/com/arialyy/simple/MainActivity.java b/app/src/main/java/com/arialyy/simple/MainActivity.java index 0fa9d955..0f09b767 100644 --- a/app/src/main/java/com/arialyy/simple/MainActivity.java +++ b/app/src/main/java/com/arialyy/simple/MainActivity.java @@ -36,8 +36,8 @@ import com.arialyy.simple.base.BaseActivity; import com.arialyy.simple.base.adapter.AbsHolder; import com.arialyy.simple.base.adapter.AbsRVAdapter; import com.arialyy.simple.base.adapter.RvItemClickSupport; -import com.arialyy.simple.core.download.m3u8.M3U8LiveDownloadActivity; -import com.arialyy.simple.core.download.m3u8.M3U8VodDownloadActivity; +import com.arialyy.simple.core.download.m3u8.M3U8LiveDLoadActivity; +import com.arialyy.simple.core.download.m3u8.M3U8VodDLoadActivity; import com.arialyy.simple.databinding.ActivityMainBinding; import com.arialyy.simple.core.download.DownloadActivity; import com.arialyy.simple.core.download.FtpDownloadActivity; @@ -110,11 +110,11 @@ public class MainActivity extends BaseActivity { break; case 6: module.startNextActivity(MainActivity.this, data.get(position), - M3U8VodDownloadActivity.class); + M3U8VodDLoadActivity.class); break; case 7: module.startNextActivity(MainActivity.this, data.get(position), - M3U8LiveDownloadActivity.class); + M3U8LiveDLoadActivity.class); break; } } 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 0a58422e..6a8b4fee 100644 --- a/app/src/main/java/com/arialyy/simple/base/BaseApplication.java +++ b/app/src/main/java/com/arialyy/simple/base/BaseApplication.java @@ -17,13 +17,10 @@ package com.arialyy.simple.base; import android.app.Application; -import android.content.IntentFilter; -import android.net.ConnectivityManager; import android.os.StrictMode; import com.arialyy.aria.core.Aria; import com.arialyy.frame.core.AbsFrame; import com.arialyy.simple.BuildConfig; -//import com.squareup.leakcanary.LeakCanary; /** * Created by Lyy on 2016/9/27. @@ -38,16 +35,16 @@ public class BaseApplication extends Application { AbsFrame.init(this); Aria.init(this); if (BuildConfig.DEBUG) { - StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() - .detectAll() - .penaltyLog() - .build()); - StrictMode.setThreadPolicy( - new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build()); + //StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() + // .detectAll() + // .penaltyLog() + // .build()); + //StrictMode.setThreadPolicy( + // new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build()); //if (LeakCanary.isInAnalyzerProcess(this)) {//1 - // This process is dedicated to LeakCanary for heap analysis. - // You should not init your app in this process. - //return; + // //This process is dedicated to LeakCanary for heap analysis. + // //You should not init your app in this process. + // return; //} //LeakCanary.install(this); } diff --git a/app/src/main/java/com/arialyy/simple/core/download/KotlinDownloadActivity.kt b/app/src/main/java/com/arialyy/simple/core/download/KotlinDownloadActivity.kt index fd93a74c..0297200a 100644 --- a/app/src/main/java/com/arialyy/simple/core/download/KotlinDownloadActivity.kt +++ b/app/src/main/java/com/arialyy/simple/core/download/KotlinDownloadActivity.kt @@ -286,15 +286,6 @@ class KotlinDownloadActivity : BaseActivity() { //.addHeader("Cookie", "BAIDUID=648E5FF020CC69E8DD6F492D1068AAA9:FG=1; BIDUPSID=648E5FF020CC69E8DD6F492D1068AAA9; PSTM=1519099573; BD_UPN=12314753; locale=zh; BDSVRTM=0") .useServerFileName(true) .setFilePath(mFilePath!!, true) - .setFileLenAdapter(IHttpFileLenAdapter { headers -> - val sLength = headers["Content-Length"] - if (sLength == null || sLength.isEmpty()) { - return@IHttpFileLenAdapter -1 - } - val temp = sLength[0] - - java.lang.Long.parseLong(temp) - }) .start() } diff --git a/app/src/main/java/com/arialyy/simple/core/download/SingleTaskActivity.java b/app/src/main/java/com/arialyy/simple/core/download/SingleTaskActivity.java index 700c51a4..528a6ec7 100644 --- a/app/src/main/java/com/arialyy/simple/core/download/SingleTaskActivity.java +++ b/app/src/main/java/com/arialyy/simple/core/download/SingleTaskActivity.java @@ -31,6 +31,7 @@ import android.view.View; import android.widget.Toast; import com.arialyy.annotations.Download; +import com.arialyy.annotations.M3U8; import com.arialyy.aria.core.Aria; import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.download.DownloadTarget; diff --git a/app/src/main/java/com/arialyy/simple/core/download/m3u8/M3U8LiveDownloadActivity.java b/app/src/main/java/com/arialyy/simple/core/download/m3u8/M3U8LiveDLoadActivity.java similarity index 92% rename from app/src/main/java/com/arialyy/simple/core/download/m3u8/M3U8LiveDownloadActivity.java rename to app/src/main/java/com/arialyy/simple/core/download/m3u8/M3U8LiveDLoadActivity.java index fb3119b4..c97fd898 100644 --- a/app/src/main/java/com/arialyy/simple/core/download/m3u8/M3U8LiveDownloadActivity.java +++ b/app/src/main/java/com/arialyy/simple/core/download/m3u8/M3U8LiveDLoadActivity.java @@ -41,7 +41,7 @@ import com.arialyy.simple.common.ModifyUrlDialog; import com.arialyy.simple.databinding.ActivityM3u8LiveBinding; import java.io.File; -public class M3U8LiveDownloadActivity extends BaseActivity { +public class M3U8LiveDLoadActivity extends BaseActivity { private String mUrl; private String mFilePath; @@ -60,7 +60,7 @@ public class M3U8LiveDownloadActivity extends BaseActivity convert(String m3u8Url, List tsUrls) { - // int index = m3u8Url.lastIndexOf("/"); - // String parentUrl = m3u8Url.substring(0, index + 1); + // int peerIndex = m3u8Url.lastIndexOf("/"); + // String parentUrl = m3u8Url.substring(0, peerIndex + 1); // List newUrls = new ArrayList<>(); // for (String url : tsUrls) { // newUrls.add(parentUrl + url); diff --git a/app/src/main/java/com/arialyy/simple/core/download/m3u8/M3U8VodDownloadActivity.java b/app/src/main/java/com/arialyy/simple/core/download/m3u8/M3U8VodDLoadActivity.java similarity index 85% rename from app/src/main/java/com/arialyy/simple/core/download/m3u8/M3U8VodDownloadActivity.java rename to app/src/main/java/com/arialyy/simple/core/download/m3u8/M3U8VodDLoadActivity.java index e26240cf..7e94a096 100644 --- a/app/src/main/java/com/arialyy/simple/core/download/m3u8/M3U8VodDownloadActivity.java +++ b/app/src/main/java/com/arialyy/simple/core/download/m3u8/M3U8VodDLoadActivity.java @@ -20,12 +20,14 @@ import android.arch.lifecycle.Observer; import android.arch.lifecycle.ViewModelProviders; import android.os.Bundle; import android.support.annotation.Nullable; +import android.support.v4.app.FragmentTransaction; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.Toast; import com.arialyy.annotations.Download; +import com.arialyy.annotations.M3U8; import com.arialyy.aria.core.Aria; import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.download.DownloadTarget; @@ -47,12 +49,13 @@ import java.io.File; import java.util.ArrayList; import java.util.List; -public class M3U8VodDownloadActivity extends BaseActivity { +public class M3U8VodDLoadActivity extends BaseActivity { private String mUrl; private String mFilePath; private M3U8VodModule mModule; private DownloadTarget mTarget; + private VideoPlayerFragment mVideoFragment; @Override protected void init(Bundle savedInstanceState) { @@ -66,7 +69,7 @@ public class M3U8VodDownloadActivity extends BaseActivity { + + static final int SEEK_BAR_PROGRESS_KEY = 0xC1; + + private M3U8VodModule mModule; + private DownloadEntity mEntity; + private int mPeerIndex; + SparseArray mPlayers = new SparseArray<>(); + private SurfaceHolder mSurfaceHolder; + private NextMediaPlayer nexPlayer; + + VideoPlayerFragment(int peerIndex, DownloadEntity entity) { + mEntity = entity; + mPeerIndex = peerIndex; + List peerInfos = entity.getM3U8Entity().getCompletedPeer(); + if (peerInfos != null) { + for (M3U8Entity.PeerInfo info : peerInfos) { + mPlayers.put(info.peerId, info.peerPath); + } + } + } + + @Override protected void init(Bundle savedInstanceState) { + mModule = ViewModelProviders.of(this).get(M3U8VodModule.class); + final MediaPlayer firstPlayer = new MediaPlayer(); + firstPlayer.setScreenOnWhilePlaying(true); + + getBinding().surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() { + @Override public void surfaceCreated(SurfaceHolder holder) { + mSurfaceHolder = holder; + firstPlayer.setSurface(holder.getSurface()); + } + + @Override + public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { + + } + + @Override public void surfaceDestroyed(SurfaceHolder holder) { + + } + }); + getBinding().seekBar.setMax(mEntity.getM3U8Entity().getPeerNum()); + getBinding().seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + + } + + @Override public void onStartTrackingTouch(SeekBar seekBar) { + + } + + @Override public void onStopTrackingTouch(SeekBar seekBar) { + dataCallback(SEEK_BAR_PROGRESS_KEY, seekBar.getProgress()); + } + }); + getBinding().controlBt.setOnClickListener(new View.OnClickListener() { + @Override public void onClick(View v) { + try { + firstPlayer.setDataSource(mPlayers.valueAt(0)); + firstPlayer.prepareAsync(); + } catch (IOException e) { + e.printStackTrace(); + } + } + }); + + firstPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { + @Override public void onPrepared(MediaPlayer mp) { + mp.start(); + setNextMediaPlayer(mp); + } + }); + + firstPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { + @Override public void onCompletion(MediaPlayer mp) { + mp.setDisplay(null); + nexPlayer.getPlayer().setSurface(mSurfaceHolder.getSurface()); + nexPlayer.start(); + } + }); + } + + /** + * 设置下一个分片 + */ + private void setNextMediaPlayer(final MediaPlayer lastPlayer) { + mPeerIndex++; + String nextPeerPath = mPlayers.get(mPeerIndex); + if (!TextUtils.isEmpty(nextPeerPath)) { + nexPlayer = new NextMediaPlayer(nextPeerPath); + nexPlayer.prepareAsync(); + + nexPlayer.setListener(new NextMediaPlayer.StateListener() { + @Override public void onStart(MediaPlayer mp) { + setNextMediaPlayer(mp); + } + + @Override public void onCompletion(MediaPlayer mp) { + mp.setDisplay(null); + nexPlayer.getPlayer().setSurface(mSurfaceHolder.getSurface()); + nexPlayer.start(); + } + + @Override public void onPrepared(MediaPlayer mp) { + lastPlayer.setNextMediaPlayer(nexPlayer.getPlayer()); + } + }); + } + } + + @Override protected int setLayoutId() { + return R.layout.fragment_video_player; + } + + public void addPlayer(int peerIndex, String peerPath) { + mPlayers.put(peerIndex, peerPath); + } + + private static class NextMediaPlayer implements MediaPlayer.OnPreparedListener, + MediaPlayer.OnErrorListener, MediaPlayer.OnCompletionListener { + private StateListener listener; + + public interface StateListener { + void onStart(MediaPlayer mp); + + void onCompletion(MediaPlayer mp); + + void onPrepared(MediaPlayer mp); + } + + private MediaPlayer player; + private String videoPath; + + private NextMediaPlayer(String videoPath) { + player = new MediaPlayer(); + player.setAudioStreamType(AudioManager.STREAM_MUSIC); + player.setOnPreparedListener(this); + player.setOnErrorListener(this); + player.setOnCompletionListener(this); + player.setScreenOnWhilePlaying(true); + this.videoPath = videoPath; + player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { + @Override public void onPrepared(MediaPlayer mp) { + if (listener != null) { + listener.onPrepared(mp); + } + } + }); + } + + private void prepareAsync() { + try { + player.setDataSource(videoPath); + player.prepareAsync(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void setListener(StateListener listener) { + this.listener = listener; + } + + public String getVideoPath() { + return videoPath; + } + + public void start() { + player.start(); + if (listener != null) { + listener.onStart(player); + } + } + + @Override public void onCompletion(MediaPlayer mp) { + if (listener != null) { + listener.onCompletion(mp); + } + } + + @Override public boolean onError(MediaPlayer mp, int what, int extra) { + return false; + } + + @Override public void onPrepared(MediaPlayer mp) { + } + + private MediaPlayer getPlayer() { + return player; + } + } +} diff --git a/app/src/main/java/com/arialyy/simple/core/download/multi_download/FileListAdapter.java b/app/src/main/java/com/arialyy/simple/core/download/multi_download/FileListAdapter.java index 9e349631..e58a1f60 100644 --- a/app/src/main/java/com/arialyy/simple/core/download/multi_download/FileListAdapter.java +++ b/app/src/main/java/com/arialyy/simple/core/download/multi_download/FileListAdapter.java @@ -104,7 +104,7 @@ final class FileListAdapter extends AbsRVAdapter " + index); + //Log.d(TAG, "peerIndex ==> " + peerIndex); return index; } } diff --git a/app/src/main/res/layout/activity_m3u8_live.xml b/app/src/main/res/layout/activity_m3u8_live.xml index 97510f96..d1b9bb02 100644 --- a/app/src/main/res/layout/activity_m3u8_live.xml +++ b/app/src/main/res/layout/activity_m3u8_live.xml @@ -35,7 +35,7 @@ /> diff --git a/app/src/main/res/layout/activity_m3u8_vod.xml b/app/src/main/res/layout/activity_m3u8_vod.xml index cbfb7566..b8f3ad62 100644 --- a/app/src/main/res/layout/activity_m3u8_vod.xml +++ b/app/src/main/res/layout/activity_m3u8_vod.xml @@ -1,6 +1,7 @@ @@ -31,12 +32,11 @@ /> + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_video_player.xml b/app/src/main/res/layout/fragment_video_player.xml new file mode 100644 index 00000000..b163de79 --- /dev/null +++ b/app/src/main/res/layout/fragment_video_player.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/network_security_config.xml b/app/src/main/res/xml/network_security_config.xml new file mode 100644 index 00000000..4ab6a7a7 --- /dev/null +++ b/app/src/main/res/xml/network_security_config.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle index d5b6dfac..f9e91beb 100644 --- a/build.gradle +++ b/build.gradle @@ -43,7 +43,7 @@ task clean(type: Delete) { ext { userOrg = 'arialyy' groupId = 'com.arialyy.aria' - publishVersion = '3.6.5_beta_2' + publishVersion = '3.6.5_beta_3' // publishVersion = '1.0.4' //FTP插件 repoName='maven' desc = 'android 下载框架'