From 11a02020dd0a417b617fa6eddda310437af4b836 Mon Sep 17 00:00:00 2001 From: AriaLyy <511455842@qq.com> Date: Thu, 15 Jun 2017 13:28:44 +0800 Subject: [PATCH] =?UTF-8?q?=E9=92=88=E5=AF=B9=E5=8D=95=E4=B8=AA=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E8=AE=BE=E7=BD=AE=E7=9B=91=E5=90=AC=E5=99=A8,=20=20ht?= =?UTF-8?q?tps://github.com/AriaLyy/Aria/issues/37?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Aria/bintray-release.gradle | 12 ++ Aria/build.gradle | 48 +---- .../arialyy/aria/core/command/CmdFactory.java | 30 ++- .../aria/core/command/ResumeAllCmd.java | 49 +++++ .../arialyy/aria/core/command/StopAllCmd.java | 20 ++ .../aria/core/download/DownloadReceiver.java | 23 +- .../core/download/DownloadTaskEntity.java | 2 + .../arialyy/aria/core/queue/AbsTaskQueue.java | 24 ++- .../arialyy/aria/core/queue/ITaskQueue.java | 17 +- .../aria/core/scheduler/AbsSchedulers.java | 2 +- AriaAnnotations/bintray-release.gradle | 12 ++ AriaAnnotations/build.gradle | 13 +- .../arialyy/annotations/AriaConstance.java | 25 +++ .../com/arialyy/annotations/Download.java | 18 +- .../java/com/arialyy/annotations/Upload.java | 13 ++ AriaCompiler/bintray-release.gradle | 12 ++ AriaCompiler/build.gradle | 13 +- .../com/arialyy/compiler/ElementHandle.java | 200 ++++++++++++++---- .../com/arialyy/compiler/ProxyConstance.java | 21 ++ .../com/arialyy/compiler/ProxyEntity.java | 3 +- .../simple/download/SingleTaskActivity.java | 68 +++--- .../fragment_download/FragmentActivity.java | 6 + .../multi_download/DownloadAdapter.java | 4 +- app/src/main/res/layout/activity_fragment.xml | 1 + build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 3 +- 26 files changed, 456 insertions(+), 185 deletions(-) create mode 100644 Aria/bintray-release.gradle create mode 100644 Aria/src/main/java/com/arialyy/aria/core/command/ResumeAllCmd.java create mode 100644 Aria/src/main/java/com/arialyy/aria/core/command/StopAllCmd.java create mode 100644 AriaAnnotations/bintray-release.gradle create mode 100644 AriaAnnotations/src/main/java/com/arialyy/annotations/AriaConstance.java create mode 100644 AriaCompiler/bintray-release.gradle diff --git a/Aria/bintray-release.gradle b/Aria/bintray-release.gradle new file mode 100644 index 00000000..37240e31 --- /dev/null +++ b/Aria/bintray-release.gradle @@ -0,0 +1,12 @@ +apply plugin: 'bintray-release' +publish { + artifactId = 'aria-core' + userOrg = rootProject.userOrg + groupId = rootProject.groupId + // uploadName = rootProject.uploadName + uploadName = 'AriaApi' + publishVersion = rootProject.publishVersion + description = rootProject.description + website = rootProject.website + licences = rootProject.licences +} \ No newline at end of file diff --git a/Aria/build.gradle b/Aria/build.gradle index 39f2e4fe..3a7a4c2e 100644 --- a/Aria/build.gradle +++ b/Aria/build.gradle @@ -1,5 +1,4 @@ apply plugin: 'com.android.library' -apply plugin: 'bintray-release' android { compileSdkVersion 23 @@ -27,49 +26,4 @@ dependencies { // compile project(':AriaAnnotations') } //apply from: 'jcenter.gradle' - -// Jar -//task androidJar(type: Jar) { -// dependsOn assemble -// group 'Build' -// description 'blah blah' -// from zipTree( -// 'build/intermediates/bundles/release/classes.jar') -// from zipTree( -// '../AriaCompiler/build/libs/AriaCompiler.jar') -// from zipTree( -// '../AriaAnnotation/build/libs/AriaAnnotation.jar') -// -//} -// -// -//// javadoc tasks -//android.libraryVariants.all { variant -> -// task("javadoc${variant.name.capitalize()}", type: Javadoc) { -// description "Generates Javadoc for $variant.name." -// group 'Docs' -// source = variant.javaCompile.source -// source "../AriaAnnotation/src/main/java" -// -// exclude '**/BuildConfig.java' -// exclude '**/R.java' -// } -//} - -publish { - artifactId = 'aria-core' - userOrg = rootProject.userOrg - groupId = rootProject.groupId - // uploadName = rootProject.uploadName - uploadName = 'AriaApi' - publishVersion = rootProject.publishVersion - description = rootProject.description - website = rootProject.website - licences = rootProject.licences -} - -//task copyJar(type: Copy) { -// from('build/libs/permission-lib.jar') -// into('../output/') -// rename ('permission-lib.jar', 'mpermissions.jar') -//} +//apply from: 'bintray-release.gradle' \ No newline at end of file diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/CmdFactory.java b/Aria/src/main/java/com/arialyy/aria/core/command/CmdFactory.java index 5be974de..ae725b51 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/command/CmdFactory.java +++ b/Aria/src/main/java/com/arialyy/aria/core/command/CmdFactory.java @@ -48,8 +48,14 @@ public class CmdFactory { * 设置任务为最高优先级 */ public static final int TASK_HIGHEST_PRIORITY = 0x128; - - public static final int TASK_SINGLE = 0x126; + /** + * 停止所有任务 + */ + public static final int TASK_STOP_ALL = 0x129; + /** + * 恢复所有停止的任务 + */ + public static final int TASK_RESUME_ALL = 0x130; private static volatile CmdFactory INSTANCE = null; @@ -70,23 +76,25 @@ public class CmdFactory { * @param target 创建任务的对象 * @param entity 下载实体 * @param type 命令类型{@link #TASK_CREATE}、{@link #TASK_START}、{@link #TASK_CANCEL}、{@link - * #TASK_STOP}、{@link #TASK_HIGHEST_PRIORITY} + * #TASK_STOP}、{@link #TASK_HIGHEST_PRIORITY}、{@link #TASK_STOP_ALL}、{@link #TASK_RESUME_ALL} */ - public AbsCmd createCmd(String target, T entity, int type) { + public AbsCmd createCmd(String target, T entity, int type) { switch (type) { case TASK_CREATE: - return new AddCmd(target, entity); + return new AddCmd<>(target, entity); case TASK_RESUME: case TASK_START: - return new StartCmd(target, entity); + return new StartCmd<>(target, entity); case TASK_CANCEL: - return new CancelCmd(target, entity); + return new CancelCmd<>(target, entity); case TASK_STOP: - return new StopCmd(target, entity); + return new StopCmd<>(target, entity); case TASK_HIGHEST_PRIORITY: - return new HighestPriorityCmd(target, entity); - case TASK_SINGLE: - //return new SingleCmd(target, entity); + return new HighestPriorityCmd<>(target, entity); + case TASK_STOP_ALL: + return new StopAllCmd<>(target, entity); + case TASK_RESUME_ALL: + return new ResumeAllCmd<>(target, entity); default: return null; } diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/ResumeAllCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/ResumeAllCmd.java new file mode 100644 index 00000000..563aacd2 --- /dev/null +++ b/Aria/src/main/java/com/arialyy/aria/core/command/ResumeAllCmd.java @@ -0,0 +1,49 @@ +package com.arialyy.aria.core.command; + +import android.util.Log; +import com.arialyy.aria.core.download.DownloadEntity; +import com.arialyy.aria.core.inf.AbsTaskEntity; +import com.arialyy.aria.core.inf.IEntity; +import com.arialyy.aria.core.inf.ITask; +import com.arialyy.aria.orm.DbEntity; +import java.util.List; + +/** + * Created by AriaL on 2017/6/13. + * 恢复所有停止的任务 + * 1.如果执行队列没有满,则开始下载任务,直到执行队列满 + * 2.如果队列执行队列已经满了,则将所有任务添加到等待队列中 + */ +final class ResumeAllCmd extends AbsCmd { + /** + * @param targetName 产生任务的对象名 + */ + ResumeAllCmd(String targetName, T entity) { + super(targetName, entity); + } + + @Override public void executeCmd() { + List allEntity = + DbEntity.findDatas(DownloadEntity.class, "state=?", IEntity.STATE_STOP + ""); + for (DownloadEntity entity : allEntity) { + int exeNum = mQueue.getExeTaskNum(); + if (exeNum == 0 || exeNum < mQueue.getMaxTaskNum()) { + ITask task = createTask(entity); + mQueue.startTask(task); + } else { + entity.setState(IEntity.STATE_WAIT); + createTask(entity); + } + } + } + + private ITask createTask(DownloadEntity entity) { + ITask task = mQueue.getTask(entity); + if (task == null) { + task = mQueue.createTask(mTargetName, mEntity); + } else { + Log.w(TAG, "添加命令执行失败,【该任务已经存在】"); + } + return task; + } +} diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/StopAllCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/StopAllCmd.java new file mode 100644 index 00000000..2c16378e --- /dev/null +++ b/Aria/src/main/java/com/arialyy/aria/core/command/StopAllCmd.java @@ -0,0 +1,20 @@ +package com.arialyy.aria.core.command; + +import com.arialyy.aria.core.inf.AbsTaskEntity; + +/** + * Created by AriaL on 2017/6/13. + * 停止所有任务的命令,并清空所有等待队列 + */ +final class StopAllCmd extends AbsCmd { + /** + * @param targetName 产生任务的对象名 + */ + StopAllCmd(String targetName, T entity) { + super(targetName, entity); + } + + @Override public void executeCmd() { + mQueue.stopAllTask(); + } +} 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 d315e9b0..b9a7d4e7 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 @@ -17,6 +17,7 @@ package com.arialyy.aria.core.download; import android.support.annotation.NonNull; import com.arialyy.aria.core.AriaManager; +import com.arialyy.aria.core.inf.ICmd; import com.arialyy.aria.core.inf.IReceiver; import com.arialyy.aria.core.command.CmdFactory; import com.arialyy.aria.core.command.AbsCmd; @@ -133,19 +134,21 @@ public class DownloadReceiver implements IReceiver { } /** - * 停止所有正在下载的任务 + * 停止所有正在下载的任务,并清空等待队列。 */ @Override public void stopAllTask() { final AriaManager ariaManager = AriaManager.getInstance(AriaManager.APP); - List allEntity = DbEntity.findAllData(DownloadEntity.class); - List stopCmds = new ArrayList<>(); - for (DownloadEntity entity : allEntity) { - if (entity.getState() == DownloadEntity.STATE_RUNNING) { - stopCmds.add( - CommonUtil.createCmd(targetName, new DownloadTaskEntity(entity), CmdFactory.TASK_STOP)); - } - } - ariaManager.setCmds(stopCmds).exe(); + ariaManager.setCmd(CmdFactory.getInstance() + .createCmd(targetName, new DownloadTaskEntity(), CmdFactory.TASK_STOP_ALL)).exe(); + } + + /** + * 恢复所有正在下载的任务 + */ + public void resumeAllTask() { + final AriaManager ariaManager = AriaManager.getInstance(AriaManager.APP); + ariaManager.setCmd(CmdFactory.getInstance() + .createCmd(targetName, new DownloadTaskEntity(), CmdFactory.TASK_RESUME_ALL)).exe(); } /** diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTaskEntity.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTaskEntity.java index 9a9fd416..75f6a17b 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTaskEntity.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTaskEntity.java @@ -25,6 +25,8 @@ public class DownloadTaskEntity extends AbsTaskEntity { public DownloadEntity downloadEntity; + public DownloadTaskEntity(){} + public DownloadTaskEntity(DownloadEntity downloadEntity) { this.downloadEntity = downloadEntity; } 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 a979739a..625d28dd 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 @@ -17,11 +17,14 @@ package com.arialyy.aria.core.queue; import android.util.Log; +import com.arialyy.aria.core.Aria; +import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.inf.AbsEntity; import com.arialyy.aria.core.inf.ITask; import com.arialyy.aria.core.inf.AbsTaskEntity; import com.arialyy.aria.core.queue.pool.CachePool; import com.arialyy.aria.core.queue.pool.ExecutePool; +import java.util.Set; /** * Created by lyy on 2017/2/23. @@ -33,6 +36,25 @@ abstract class AbsTaskQueue mCachePool = new CachePool<>(); ExecutePool mExecutePool; + /** + * 停止所有任务 + */ + @Override public void stopAllTask() { + Set exeKeys = mExecutePool.getAllTask().keySet(); + for (String key : exeKeys) { + TASK task = mExecutePool.getAllTask().get(key); + if (task != null && task.isRunning()) task.stop(); + } + Set cacheKeys = mCachePool.getAllTask().keySet(); + for (String key : cacheKeys) { + mExecutePool.removeTask(key); + } + } + + @Override public int getMaxTaskNum() { + return AriaManager.getInstance(AriaManager.APP).getDownloadConfig().getMaxTaskNum(); + } + /** * 获取任务执行池 */ @@ -61,7 +83,7 @@ abstract class AbsTaskQueue { + /** + * 停止所有任务 + */ + void stopAllTask(); + /** * 设置任务为最高优先级任务 + * * @param task {@link DownloadTask}、{@link UploadTask} */ void setTaskHighestPriority(TASK task); @@ -67,9 +73,9 @@ public interface ITaskQueue * + * {@literal @}Download.onPre(DownloadUrl) * protected void onPre(DownloadTask task) { - * if (task.getKey().equals(DOWNLOAD_URL)) { - * mUpdateHandler.obtainMessage(DOWNLOAD_PRE, task.getDownloadEntity().getFileSize()).sendToTarget(); - * } + * mUpdateHandler.obtainMessage(DOWNLOAD_PRE, task.getDownloadEntity().getFileSize()).sendToTarget(); * } * * + * {@literal @}Download.onPre("http://www.baidu.com"),如果你的注解中增加了url描述, + * 则表示,所有下载任务中,只有下载地址为"http://www.baidu.com"的任务才能回调该注解的方法。 */ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface Download { /** * 如果你在方法中添加{@code @Download.onPre}注解,在预处理完成时,Aria会调用该方法 */ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onPre { + String[] value() default { AriaConstance.NO_URL }; } /** * 如果你在方法中添加{@code @Download.onTaskPre}注解,在任务预处理完成时,Aria会调用该方法 */ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskPre { + String[] value() default { AriaConstance.NO_URL }; } /** * 如果你在方法中添加{@code @Download.onTaskResume}注解,在任务恢复下载时,Aria会调用该方法 */ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskResume { + String[] value() default { AriaConstance.NO_URL }; } + /** * 如果你在方法中添加{@code @Download.onTaskStart}注解,在任务开始下载时,Aria会调用该方法 */ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskStart { + String[] value() default { AriaConstance.NO_URL }; } /** * 如果你在方法中添加{@code @Download.onTaskStop}注解,在任务停止时,Aria会调用该方法 */ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskStop { + String[] value() default { AriaConstance.NO_URL }; } /** * 如果你在方法中添加{@code @Download.onTaskCancel}l注解,在任务取消时,Aria会调用该方法 */ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskCancel { + String[] value() default { AriaConstance.NO_URL }; } /** * 如果你在方法中添加{@code @Download.onTaskFail)注解,在任务预失败时,Aria会调用该方法 */ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskFail { + String[] value() default { AriaConstance.NO_URL }; } /** * 如果你在方法中添加{@code @Download.onTaskComplete}注解,在任务完成时,Aria会调用该方法 */ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskComplete { + String[] value() default { AriaConstance.NO_URL }; } /** * 如果你在方法中添加{@code @Download.onTaskRunning}注解,在任务正在下载,Aria会调用该方法 */ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskRunning { + String[] value() default { AriaConstance.NO_URL }; } /** @@ -92,5 +103,6 @@ import java.lang.annotation.Target; */ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onNoSupportBreakPoint { + String[] value() default { AriaConstance.NO_URL }; } } diff --git a/AriaAnnotations/src/main/java/com/arialyy/annotations/Upload.java b/AriaAnnotations/src/main/java/com/arialyy/annotations/Upload.java index bf1a2cd1..7906bcc7 100644 --- a/AriaAnnotations/src/main/java/com/arialyy/annotations/Upload.java +++ b/AriaAnnotations/src/main/java/com/arialyy/annotations/Upload.java @@ -25,11 +25,14 @@ import java.lang.annotation.Target; * Aria下载事件被注解的方法中,参数仅能有一个,参数类型为{@link com.arialyy.aria.core.upload.UploadTask} *
  *   
+ *      {@literal @}Upload.onPre
  *       protected void onPre(UploadTask task) {
  *        L.d(TAG, "fileSize = " + task.getConvertFileSize());
  *       }
  *   
  * 
+ * {@literal @}Upload.onPre("/mnt/sdcard/test.zip"),如果你的注解中增加了path描述, + * 则表示,所有上传任务中,只有上传路径为"/mnt/sdcard/test.zip"的任务才能回调该注解的方法。 */ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface Upload { @@ -37,12 +40,14 @@ import java.lang.annotation.Target; * 如果你在方法中添加{@code @Upload.onPre}注解,在预处理完成时,Aria会调用该方法 */ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onPre { + String[] value() default { AriaConstance.NO_URL }; } /** * 如果你在方法中添加{@code @Upload.onTaskPre}注解,在任务预处理完成时,Aria会调用该方法 */ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskPre { + String[] value() default { AriaConstance.NO_URL }; } /** @@ -50,40 +55,47 @@ import java.lang.annotation.Target; */ //@Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskResume { //} + /** * 如果你在方法中添加{@code @Upload.onTaskStart}注解,在任务开始下载时,Aria会调用该方法 */ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskStart { + String[] value() default { AriaConstance.NO_URL }; } /** * 如果你在方法中添加{@code @Upload.onTaskStop}注解,在任务停止时,Aria会调用该方法 */ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskStop { + String[] value() default { AriaConstance.NO_URL }; } /** * 如果你在方法中添加{@code @Upload.onTaskCancel}l注解,在任务取消时,Aria会调用该方法 */ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskCancel { + String[] value() default { AriaConstance.NO_URL }; } /** * 如果你在方法中添加{@code @Upload.onTaskFail)注解,在任务预失败时,Aria会调用该方法 */ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskFail { + String[] value() default { AriaConstance.NO_URL }; } /** * 如果你在方法中添加{@code @Upload.onTaskComplete}注解,在任务完成时,Aria会调用该方法 */ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskComplete { + String[] value() default { AriaConstance.NO_URL }; } /** * 如果你在方法中添加{@code @Upload.onTaskRunning}注解,在任务正在下载,Aria会调用该方法 */ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskRunning { + String[] value() default { AriaConstance.NO_URL }; } /** @@ -91,5 +103,6 @@ import java.lang.annotation.Target; */ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onNoSupportBreakPoint { + String[] value() default { AriaConstance.NO_URL }; } } diff --git a/AriaCompiler/bintray-release.gradle b/AriaCompiler/bintray-release.gradle new file mode 100644 index 00000000..7fb12803 --- /dev/null +++ b/AriaCompiler/bintray-release.gradle @@ -0,0 +1,12 @@ +apply plugin: 'bintray-release' +publish { + artifactId = 'aria-compiler' + userOrg = rootProject.userOrg + groupId = rootProject.groupId + // uploadName = rootProject.uploadName + uploadName = 'AriaCompiler' + publishVersion = rootProject.publishVersion + description = rootProject.description + website = rootProject.website + licences = rootProject.licences +} \ No newline at end of file diff --git a/AriaCompiler/build.gradle b/AriaCompiler/build.gradle index 3e915676..38de01a1 100644 --- a/AriaCompiler/build.gradle +++ b/AriaCompiler/build.gradle @@ -1,5 +1,4 @@ apply plugin: 'java' -apply plugin: 'bintray-release' tasks.withType(JavaCompile) { options.encoding = "UTF-8" @@ -15,14 +14,4 @@ dependencies { compile project(':AriaAnnotations') } -publish { - artifactId = 'aria-compiler' - userOrg = rootProject.userOrg - groupId = rootProject.groupId -// uploadName = rootProject.uploadName - uploadName = 'AriaCompiler' - publishVersion = rootProject.publishVersion - description = rootProject.description - website = rootProject.website - licences = rootProject.licences -} \ No newline at end of file +//apply from: 'bintray-release.gradle' \ No newline at end of file diff --git a/AriaCompiler/src/main/java/com/arialyy/compiler/ElementHandle.java b/AriaCompiler/src/main/java/com/arialyy/compiler/ElementHandle.java index 3ec58d74..4e918479 100644 --- a/AriaCompiler/src/main/java/com/arialyy/compiler/ElementHandle.java +++ b/AriaCompiler/src/main/java/com/arialyy/compiler/ElementHandle.java @@ -18,6 +18,7 @@ package com.arialyy.compiler; import com.arialyy.annotations.Download; 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; @@ -26,7 +27,9 @@ import com.squareup.javapoet.TypeSpec; import com.squareup.javapoet.ParameterizedTypeName; import java.io.IOException; import java.lang.annotation.Annotation; +import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -63,40 +66,32 @@ class ElementHandle { * PackageElement 一般代表Package */ void handleDownload(RoundEnvironment roundEnv) { - saveMethod(true, roundEnv, Download.onNoSupportBreakPoint.class); - saveMethod(true, roundEnv, Download.onPre.class); - saveMethod(true, roundEnv, Download.onTaskCancel.class); - saveMethod(true, roundEnv, Download.onTaskComplete.class); - saveMethod(true, roundEnv, Download.onTaskFail.class); - saveMethod(true, roundEnv, Download.onTaskPre.class); - saveMethod(true, roundEnv, Download.onTaskResume.class); - saveMethod(true, roundEnv, Download.onTaskRunning.class); - saveMethod(true, roundEnv, Download.onTaskStart.class); - saveMethod(true, roundEnv, Download.onTaskStop.class); + saveMethod(true, roundEnv, Download.onNoSupportBreakPoint.class, + ProxyConstance.DOWNLOAD_TASK_NO_SUPPORT_BREAKPOINT); + saveMethod(true, roundEnv, Download.onPre.class, ProxyConstance.DOWNLOAD_PRE); + saveMethod(true, roundEnv, Download.onTaskCancel.class, ProxyConstance.DOWNLOAD_TASK_CANCEL); + saveMethod(true, roundEnv, Download.onTaskComplete.class, + ProxyConstance.DOWNLOAD_TASK_COMPLETE); + saveMethod(true, roundEnv, Download.onTaskFail.class, ProxyConstance.DOWNLOAD_TASK_FAIL); + saveMethod(true, roundEnv, Download.onTaskPre.class, ProxyConstance.DOWNLOAD_TASK_PRE); + saveMethod(true, roundEnv, Download.onTaskResume.class, ProxyConstance.DOWNLOAD_TASK_RESUME); + saveMethod(true, roundEnv, Download.onTaskRunning.class, ProxyConstance.DOWNLOAD_TASK_RUNNING); + saveMethod(true, roundEnv, Download.onTaskStart.class, ProxyConstance.DOWNLOAD_TASK_START); + saveMethod(true, roundEnv, Download.onTaskStop.class, ProxyConstance.DOWNLOAD_TASK_STOP); } void handleUpload(RoundEnvironment roundEnv) { - saveMethod(false, roundEnv, Upload.onNoSupportBreakPoint.class); - saveMethod(false, roundEnv, Upload.onPre.class); - saveMethod(false, roundEnv, Upload.onTaskCancel.class); - saveMethod(false, roundEnv, Upload.onTaskComplete.class); - saveMethod(false, roundEnv, Upload.onTaskFail.class); - saveMethod(false, roundEnv, Upload.onTaskPre.class); + saveMethod(false, roundEnv, Upload.onNoSupportBreakPoint.class, + ProxyConstance.UPLOAD_TASK_NO_SUPPORT_BREAKPOINT); + saveMethod(false, roundEnv, Upload.onPre.class, ProxyConstance.UPLOAD_PRE); + saveMethod(false, roundEnv, Upload.onTaskCancel.class, ProxyConstance.UPLOAD_TASK_CANCEL); + saveMethod(false, roundEnv, Upload.onTaskComplete.class, ProxyConstance.UPLOAD_TASK_COMPLETE); + saveMethod(false, roundEnv, Upload.onTaskFail.class, ProxyConstance.UPLOAD_TASK_FAIL); + saveMethod(false, roundEnv, Upload.onTaskPre.class, ProxyConstance.UPLOAD_TASK_PRE); //saveMethod(false, roundEnv, Upload.onTaskResume.class); - saveMethod(false, roundEnv, Upload.onTaskRunning.class); - saveMethod(false, roundEnv, Upload.onTaskStart.class); - saveMethod(false, roundEnv, Upload.onTaskStop.class); - } - - void printMethods() { - //Set keys = mMethods.keySet(); - //for (String key : keys) { - // ProxyEntity entity = mMethods.get(key); - // for (String method : entity.methods) { - // PrintLog.getInstance().info(method); - // } - //} - PrintLog.getInstance().info("size ==> " + mMethods.size()); + saveMethod(false, roundEnv, Upload.onTaskRunning.class, ProxyConstance.UPLOAD_TASK_RUNNING); + saveMethod(false, roundEnv, Upload.onTaskStart.class, ProxyConstance.UPLOAD_TASK_START); + saveMethod(false, roundEnv, Upload.onTaskStop.class, ProxyConstance.UPLOAD_TASK_STOP); } /** @@ -157,16 +152,29 @@ class ElementHandle { isDownload ? "DownloadTask" : "UploadTask"); ParameterSpec parameterSpec = ParameterSpec.builder(task, "task").addModifiers(Modifier.FINAL).build(); + StringBuilder sb = new StringBuilder(); + sb.append("Set keys = keyMapping.get(\"") + .append(annotation.getSimpleName()) + .append("\");\n"); + sb.append("if (keys != null) {\n\tif (keys.contains(task.getKey())) {\n") + .append("\t\tobj.") + .append(methodName) + .append("(") + .append(isDownload ? "(DownloadTask)" : "(UploadTask)") + .append("task);\n") + .append("\t}\n} else {\n") + .append("\tobj.") + .append(methodName) + .append("(") + .append(isDownload ? "(DownloadTask)" : "(UploadTask)") + .append("task);\n}\n"); + return MethodSpec.methodBuilder(annotation.getSimpleName()) .addModifiers(Modifier.PUBLIC) .returns(void.class) .addParameter(parameterSpec) .addAnnotation(Override.class) - .addCode("obj." - + methodName - + "(" - + (isDownload ? "(DownloadTask)" : "(UploadTask)") - + "task);\n") + .addCode(sb.toString()) .build(); } @@ -184,6 +192,13 @@ class ElementHandle { FieldSpec observerField = FieldSpec.builder(obj, "obj").addModifiers(Modifier.PRIVATE).build(); builder.addField(observerField); + //添加url映射表 + FieldSpec mappingField = FieldSpec.builder( + ParameterizedTypeName.get(ClassName.get(Map.class), ClassName.get(String.class), + ParameterizedTypeName.get(ClassName.get(Set.class), ClassName.get(String.class))), + "keyMapping").addModifiers(Modifier.PRIVATE).initializer("new $T()", HashMap.class).build(); + builder.addField(mappingField); + //添加注解方法 for (Class annotation : entity.methods.keySet()) { MethodSpec method = @@ -191,6 +206,26 @@ class ElementHandle { builder.addMethod(method); } + //增加构造函数 + CodeBlock.Builder cb = CodeBlock.builder(); + cb.add("Set set = null;\n"); + for (String methodName : entity.keyMappings.keySet()) { + Set keys = entity.keyMappings.get(methodName); + if (keys == null || keys.size() == 0) continue; + StringBuilder sb = new StringBuilder(); + sb.append("set = new $T();\n"); + for (String key : keys) { + if (key.isEmpty()) continue; + sb.append("set.add(\"").append(key).append("\");\n"); + } + + sb.append("keyMapping.put(\"").append(methodName).append("\", ").append("set);\n"); + cb.add(sb.toString(), ClassName.get(HashSet.class)); + } + MethodSpec structure = + MethodSpec.constructorBuilder().addModifiers(Modifier.PUBLIC).addCode(cb.build()).build(); + builder.addMethod(structure); + //添加设置代理的类 ParameterSpec parameterSpec = ParameterSpec.builder(Object.class, "obj").addModifiers(Modifier.FINAL).build(); @@ -222,7 +257,7 @@ class ElementHandle { * 查找并保存扫描到的方法 */ private void saveMethod(boolean isDownload, RoundEnvironment roundEnv, - Class annotationClazz) { + Class annotationClazz, int annotationType) { for (Element element : roundEnv.getElementsAnnotatedWith(annotationClazz)) { ElementKind kind = element.getKind(); if (kind == ElementKind.METHOD) { @@ -236,16 +271,92 @@ class ElementHandle { if (proxyEntity == null) { proxyEntity = new ProxyEntity(); proxyEntity.isDownlaod = isDownload; - //proxyEntity.packageName = classElement.getQualifiedName().toString(); proxyEntity.packageName = packageElement.getQualifiedName().toString(); proxyEntity.className = classElement.getSimpleName().toString(); mMethods.put(className, proxyEntity); } proxyEntity.methods.put(annotationClazz, methodName); + proxyEntity.keyMappings.put(methodName, getValues(method, isDownload, annotationType)); } } } + /** + * 获取注解的内容 + */ + private Set getValues(ExecutableElement method, boolean isDownload, int annotationType) { + String[] keys = null; + if (isDownload) { + switch (annotationType) { + case ProxyConstance.DOWNLOAD_PRE: + keys = method.getAnnotation(Download.onPre.class).value(); + break; + case ProxyConstance.DOWNLOAD_TASK_PRE: + keys = method.getAnnotation(Download.onTaskPre.class).value(); + break; + case ProxyConstance.DOWNLOAD_TASK_RESUME: + keys = method.getAnnotation(Download.onTaskResume.class).value(); + break; + case ProxyConstance.DOWNLOAD_TASK_START: + keys = method.getAnnotation(Download.onTaskStart.class).value(); + break; + case ProxyConstance.DOWNLOAD_TASK_RUNNING: + keys = method.getAnnotation(Download.onTaskRunning.class).value(); + break; + case ProxyConstance.DOWNLOAD_TASK_STOP: + keys = method.getAnnotation(Download.onTaskStop.class).value(); + break; + case ProxyConstance.DOWNLOAD_TASK_COMPLETE: + keys = method.getAnnotation(Download.onTaskComplete.class).value(); + break; + case ProxyConstance.DOWNLOAD_TASK_CANCEL: + keys = method.getAnnotation(Download.onTaskCancel.class).value(); + break; + case ProxyConstance.DOWNLOAD_TASK_FAIL: + keys = method.getAnnotation(Download.onTaskFail.class).value(); + break; + case ProxyConstance.DOWNLOAD_TASK_NO_SUPPORT_BREAKPOINT: + keys = method.getAnnotation(Download.onNoSupportBreakPoint.class).value(); + break; + } + } else { + switch (annotationType) { + case ProxyConstance.UPLOAD_PRE: + keys = method.getAnnotation(Upload.onPre.class).value(); + break; + case ProxyConstance.UPLOAD_TASK_PRE: + keys = method.getAnnotation(Upload.onTaskPre.class).value(); + break; + case ProxyConstance.UPLOAD_TASK_RESUME: + //keys = method.getAnnotation(Upload.onTaskResume.class).value(); + break; + case ProxyConstance.UPLOAD_TASK_START: + keys = method.getAnnotation(Upload.onTaskStart.class).value(); + break; + case ProxyConstance.UPLOAD_TASK_RUNNING: + keys = method.getAnnotation(Upload.onTaskRunning.class).value(); + break; + case ProxyConstance.UPLOAD_TASK_STOP: + keys = method.getAnnotation(Upload.onTaskStop.class).value(); + break; + case ProxyConstance.UPLOAD_TASK_COMPLETE: + keys = method.getAnnotation(Upload.onTaskComplete.class).value(); + break; + case ProxyConstance.UPLOAD_TASK_CANCEL: + keys = method.getAnnotation(Upload.onTaskCancel.class).value(); + break; + case ProxyConstance.UPLOAD_TASK_FAIL: + keys = method.getAnnotation(Upload.onTaskFail.class).value(); + break; + case ProxyConstance.UPLOAD_TASK_NO_SUPPORT_BREAKPOINT: + keys = method.getAnnotation(Upload.onNoSupportBreakPoint.class).value(); + break; + } + } + + return keys == null ? null : convertSet(keys); + } + /** * 检查和下载相关的方法,如果被注解的方法为private或参数不合法,则抛异常 */ @@ -272,6 +383,21 @@ class ElementHandle { } } + /** + * 字符串数组转set + * + * @param keys 注解中查到的key + */ + private Set convertSet(final String[] keys) { + if (keys == null || keys.length == 0) { + return null; + } + if (keys[0].isEmpty()) return null; + Set set = new HashSet<>(); + Collections.addAll(set, keys); + return set; + } + private String getCheckParams(boolean isDownload) { return isDownload ? "com.arialyy.aria.core.download.DownloadTask" : "com.arialyy.aria.core.upload.UploadTask"; diff --git a/AriaCompiler/src/main/java/com/arialyy/compiler/ProxyConstance.java b/AriaCompiler/src/main/java/com/arialyy/compiler/ProxyConstance.java index 7e9ac1ea..6ea65c33 100644 --- a/AriaCompiler/src/main/java/com/arialyy/compiler/ProxyConstance.java +++ b/AriaCompiler/src/main/java/com/arialyy/compiler/ProxyConstance.java @@ -35,4 +35,25 @@ public interface ProxyConstance { */ String UPLOAD_PROXY_CLASS_SUFFIX = "$$UploadListenerProxy"; + int DOWNLOAD_PRE = 0X11; + int DOWNLOAD_TASK_PRE = 0X12; + int DOWNLOAD_TASK_RESUME = 0X13; + int DOWNLOAD_TASK_START = 0X14; + int DOWNLOAD_TASK_STOP = 0X15; + int DOWNLOAD_TASK_CANCEL = 0X16; + int DOWNLOAD_TASK_FAIL = 0X17; + int DOWNLOAD_TASK_COMPLETE = 0X18; + int DOWNLOAD_TASK_RUNNING = 0X19; + int DOWNLOAD_TASK_NO_SUPPORT_BREAKPOINT = 0X1A; + + int UPLOAD_PRE = 0X11; + int UPLOAD_TASK_PRE = 0X12; + int UPLOAD_TASK_RESUME = 0X13; + int UPLOAD_TASK_START = 0X14; + int UPLOAD_TASK_STOP = 0X15; + int UPLOAD_TASK_CANCEL = 0X16; + int UPLOAD_TASK_FAIL = 0X17; + int UPLOAD_TASK_COMPLETE = 0X18; + int UPLOAD_TASK_RUNNING = 0X19; + int UPLOAD_TASK_NO_SUPPORT_BREAKPOINT = 0X1A; } diff --git a/AriaCompiler/src/main/java/com/arialyy/compiler/ProxyEntity.java b/AriaCompiler/src/main/java/com/arialyy/compiler/ProxyEntity.java index 9c6e9070..41573cfc 100644 --- a/AriaCompiler/src/main/java/com/arialyy/compiler/ProxyEntity.java +++ b/AriaCompiler/src/main/java/com/arialyy/compiler/ProxyEntity.java @@ -18,6 +18,7 @@ package com.arialyy.compiler; import java.lang.annotation.Annotation; import java.util.HashMap; import java.util.Map; +import java.util.Set; /** * Created by Aria.Lao on 2017/6/7. @@ -27,6 +28,6 @@ class ProxyEntity { public String packageName; public String className; public boolean isDownlaod = true; - + public Map> keyMappings = new HashMap<>(); public Map, String> methods = new HashMap<>(); } diff --git a/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java b/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java index 144b96c3..79717755 100644 --- a/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java +++ b/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java @@ -63,8 +63,8 @@ public class SingleTaskActivity extends BaseActivity { //"http://kotlinlang.org/docs/kotlin-docs.pdf"; //"https://atom-installer.github.com/v1.13.0/AtomSetup.exe?s=1484074138&ext=.exe"; "http://static.gaoshouyou.com/d/22/94/822260b849944492caadd2983f9bb624.apk"; - //"http://tinghuaapp.oss-cn-shanghai.aliyuncs.com/20170612201739607815"; - //"http://static.gaoshouyou.com/d/36/69/2d3699acfa69e9632262442c46516ad8.apk"; + //"http://tinghuaapp.oss-cn-shanghai.aliyuncs.com/20170612201739607815"; + //"http://static.gaoshouyou.com/d/36/69/2d3699acfa69e9632262442c46516ad8.apk"; //"http://oqcpqqvuf.bkt.clouddn.com/ceshi.txt"; //"http://down8.androidgame-store.com/201706122321/97967927DD4E53D9905ECAA7874C8128/new/game1/19/45319/com.neuralprisma-2.5.2.174-2000174_1494784835.apk?f=web_1"; //不支持断点的链接 @@ -182,63 +182,45 @@ public class SingleTaskActivity extends BaseActivity { return true; } - @Download.onPre protected void onPre(DownloadTask task) { - if (task.getKey().equals(DOWNLOAD_URL)) { - mUpdateHandler.obtainMessage(DOWNLOAD_PRE, task.getDownloadEntity().getFileSize()) - .sendToTarget(); - } + @Download.onPre(DOWNLOAD_URL) protected void onPre(DownloadTask task) { + mUpdateHandler.obtainMessage(DOWNLOAD_PRE, task.getDownloadEntity().getFileSize()) + .sendToTarget(); } - @Download.onTaskStart void taskStart(DownloadTask task) { - //通过下载地址可以判断任务是否是你指定的任务 - if (task.getKey().equals(DOWNLOAD_URL)) { - mUpdateHandler.obtainMessage(DOWNLOAD_START, task.getDownloadEntity().getFileSize()) - .sendToTarget(); - } + @Download.onTaskStart(DOWNLOAD_URL) void taskStart(DownloadTask task) { + mUpdateHandler.obtainMessage(DOWNLOAD_START, task.getDownloadEntity().getFileSize()) + .sendToTarget(); } - @Download.onTaskRunning protected void running(DownloadTask task) { - if (task.getKey().equals(DOWNLOAD_URL)) { - mUpdateHandler.obtainMessage(DOWNLOAD_RUNNING, task).sendToTarget(); - } + @Download.onTaskRunning(DOWNLOAD_URL) protected void running(DownloadTask task) { + mUpdateHandler.obtainMessage(DOWNLOAD_RUNNING, task).sendToTarget(); } - @Download.onTaskResume void taskResume(DownloadTask task) { - if (task.getKey().equals(DOWNLOAD_URL)) { - mUpdateHandler.obtainMessage(DOWNLOAD_START, task.getFileSize()).sendToTarget(); - } + @Download.onTaskResume(DOWNLOAD_URL) void taskResume(DownloadTask task) { + mUpdateHandler.obtainMessage(DOWNLOAD_START, task.getFileSize()).sendToTarget(); } - @Download.onTaskStop void taskStop(DownloadTask task) { - if (task.getKey().equals(DOWNLOAD_URL)) { - mUpdateHandler.sendEmptyMessage(DOWNLOAD_STOP); - L.d(TAG, "task__stop"); - } + @Download.onTaskStop(DOWNLOAD_URL) void taskStop(DownloadTask task) { + mUpdateHandler.sendEmptyMessage(DOWNLOAD_STOP); + L.d(TAG, "task__stop"); } - @Download.onTaskCancel void taskCancel(DownloadTask task) { - if (task.getKey().equals(DOWNLOAD_URL)) { - mUpdateHandler.sendEmptyMessage(DOWNLOAD_CANCEL); - L.d(TAG, "task__cancel"); - } + @Download.onTaskCancel(DOWNLOAD_URL) void taskCancel(DownloadTask task) { + mUpdateHandler.sendEmptyMessage(DOWNLOAD_CANCEL); + L.d(TAG, "task__cancel"); } - @Download.onTaskFail void taskFail(DownloadTask task) { - if (task.getKey().equals(DOWNLOAD_URL)) { - mUpdateHandler.sendEmptyMessage(DOWNLOAD_FAILE); - } + @Download.onTaskFail(DOWNLOAD_URL) void taskFail(DownloadTask task) { + mUpdateHandler.sendEmptyMessage(DOWNLOAD_FAILE); } - @Download.onTaskComplete void taskComplete(DownloadTask task) { - if (task.getKey().equals(DOWNLOAD_URL)) { - mUpdateHandler.sendEmptyMessage(DOWNLOAD_COMPLETE); - } + @Download.onTaskComplete(DOWNLOAD_URL) void taskComplete(DownloadTask task) { + mUpdateHandler.sendEmptyMessage(DOWNLOAD_COMPLETE); } - @Download.onNoSupportBreakPoint public void onNoSupportBreakPoint(DownloadTask task) { - if (task.getKey().equals(DOWNLOAD_URL)) { - T.showShort(SingleTaskActivity.this, "该下载链接不支持断点"); - } + @Download.onNoSupportBreakPoint(DOWNLOAD_URL) + public void onNoSupportBreakPoint(DownloadTask task) { + T.showShort(SingleTaskActivity.this, "该下载链接不支持断点"); } @Override protected int setLayoutId() { diff --git a/app/src/main/java/com/arialyy/simple/download/fragment_download/FragmentActivity.java b/app/src/main/java/com/arialyy/simple/download/fragment_download/FragmentActivity.java index 9b3c48cb..93ab023f 100644 --- a/app/src/main/java/com/arialyy/simple/download/fragment_download/FragmentActivity.java +++ b/app/src/main/java/com/arialyy/simple/download/fragment_download/FragmentActivity.java @@ -16,6 +16,7 @@ package com.arialyy.simple.download.fragment_download; +import android.os.Bundle; import com.arialyy.simple.R; import com.arialyy.simple.base.BaseActivity; import com.arialyy.simple.databinding.FragmentDownloadBinding; @@ -28,4 +29,9 @@ public class FragmentActivity extends BaseActivity { @Override protected int setLayoutId() { return R.layout.activity_fragment; } + + @Override protected void init(Bundle savedInstanceState) { + super.init(savedInstanceState); + setTile("Fragment 中使用"); + } } diff --git a/app/src/main/java/com/arialyy/simple/download/multi_download/DownloadAdapter.java b/app/src/main/java/com/arialyy/simple/download/multi_download/DownloadAdapter.java index d05e51a4..1d26aeaf 100644 --- a/app/src/main/java/com/arialyy/simple/download/multi_download/DownloadAdapter.java +++ b/app/src/main/java/com/arialyy/simple/download/multi_download/DownloadAdapter.java @@ -152,8 +152,8 @@ public class DownloadAdapter extends AbsRVAdapter +