From 18c7a9409ae2f706cdfe0ddf5ef4cc1a3970b453 Mon Sep 17 00:00:00 2001 From: liuyuchuan Date: Sun, 30 Jun 2019 13:22:23 +0800 Subject: [PATCH] 1. add proguard 2. add Chinese readme --- README-zh.md | 247 ++++++++++++++++++ README.md | 29 +- config.gradle | 2 +- downloader/build.gradle | 1 + downloader/proguard-rules.pro | 91 +++++-- .../lyc/downloader/BaseServiceManager.java | 2 +- .../DownloadListenerDispatcher.java | 2 +- keys/keystore.properties | 4 + keys/test.jks | Bin 0 -> 2070 bytes sample/build.gradle | 18 +- sample/proguard-rules.pro | 88 +++++++ .../java/com/lyc/yuchuan_downloader/App.kt | 5 +- 12 files changed, 454 insertions(+), 35 deletions(-) create mode 100644 README-zh.md create mode 100644 keys/keystore.properties create mode 100644 keys/test.jks diff --git a/README-zh.md b/README-zh.md new file mode 100644 index 0000000..8d2a1bd --- /dev/null +++ b/README-zh.md @@ -0,0 +1,247 @@ +# YC-Downloader + +[![](https://jitpack.io/v/SirLYC/YC-Downloader.svg)](https://jitpack.io/#SirLYC/YC-Downloader) + +多线程、多任务、多进程下载库,支持断点续传、限速等... + +## Features +- [x] HTTP/HTTPS下载 +- [x] 多线程下载 +- [x] 下载(生产者)线程与写磁盘(消费者)线程分离 +- [x] 多任务管理 +- [x] 断点续传 +- [x] 消息控制避免UI卡顿 +- [x] 多进程支持 +- [x] 下载限速 +- [x] 自动重试(下载和连接) +- [ ] 有时间支持其他协议下载... + +## 项目 +**`sample` module** + + 一个用该库实现的简单app,显示了库的特性。 + +**`downloader` module** + + 下载库。 + + +## 集成 +**Step 1.** 添加JitPack repository到根目录的build.gradle + +``` groovy +allprojects { + repositories { + ... + maven { url 'https://jitpack.io' } + } +} +``` + +**Step 2.** 添加依赖 + +``` groovy +dependencies { + implementation 'com.github.SirLYC:Yuchuan-Downloader:latest.release' +} +``` + +> [Check release notes here](https://github.com/SirLYC/YC-Downloader/releases) + +**Step3.** 安装库 + +在`manifest`文件中: + +``` xml + + + + + + + ... + + ... + + + + + + + ... + + +``` + +推荐在`Application`中集成 + +``` kotlin +class App : Application() { + override fun onCreate() { + super.onCreate() + + val config = Configuration.Builder() + // 是否使用多进程 + // 如果使用YCDownloader.install(Context) + // 这个参数的值由你在manifest中指定的Service为准 + // 如果都指定了,为true + // 如果使用YCDownloader.install(Context, Configuration) + // 传入参数对应的Service必须指定 + .setMultiProcess(false) + // 是否允许下载,如果不允许,所有任务都在等待状态 + // 这个参数可以用来做运营商网络等待wifi连接 + .setAllowDownload(true) + // 是否控制进度更新消息 + .setAvoidFrameDrop(true) + // 最大同时运行任务数量 + .setMaxRunningTask(4) + // 通过Listener接收进度更新消息间隔,纳秒为单位 + .setSendMessageIntervalNanos(TimeUnit.MILLISECONDS.toNanos(333)) + // 限速,字节/秒为单位。如果传0或没有设置,不限速 +// .setSpeedLimit(2048 * 1024) + .setSpeedLimit(0) + .build() + + YCDownloader.install(this, config) + +// YCDownloader.install(this) + } +} +``` + +## 混淆配置 + +`Proguard` 已经在依赖中配置,无须单独配置。 + +## 主要API + +所有的API都可以在这个文件中看到: [YCDownloader.java](https://github.com/SirLYC/YC-Downloader/blob/master/downloader/src/main/java/com/lyc/downloader/YCDownloader.java) + + +**提交任务** +``` java +private SubmitListener submitListener = new SubmitListener() { + @Override + public void submitSuccess(DownloadInfo downloadInfo) { + Log.d("Submit", "success submit, id = " + downloadInfo.getId()); + } + + @Override + public void submitFail(Exception e) { + Log.e("Submit", "submit failed", e); + } +}; +// path: 存储文件的路径 +// filename: 可以是null;当为null时,文件名由下载器决定 +YCDownloader.submit(url, path, filename, submitListener); +``` + +**监听下载进度** +``` java +DownloadListener downloadListener = ...; +YCDownloader.registerDownloadListener(downloadListener); + +// 及时注销避免内存泄漏 +// 比如在Activity.OnDestroy +YCDownloader.unregisterDownloadListener(downloadListener); +``` + +**查询任务信息** +``` java +// 注意:这些方法不能再主线程使用 +// query by id +YCDownloader.queryDownloadInfo(long id); +// state != CANCELED && state != FINISH +YCDownloader.queryActiveDownloadInfoList(); +// state == DELETED +YCDownloader.queryDeletedDownloadInfoList(); +// state == FINISH +YCDownloader.queryFinishedDownloadInfoList(); +``` + +**配置** + +在下载器运行时,一些配置是可以改变的。这些方法都是线程安全的。 + +``` java +// 最大任务数设置为4 +YCDownloader.setMaxRunningTask(4); + +// 限速512KB/s +YCDownloader.setSpeedLimit(512 * 1024); + +// 避免主线程接收过多进度更新消息而卡顿 +YCDownloader.setAvoidFrameDrop(true); +//接收进度更新间隔 +YCDownloader.setSendMessageInterval(500, TimeUnit.MILLISECONDS); + +// 如果为false,所有任务都在等待状态 +YCDownloaer.setAllowDownload(true) + +// 批量更新参数,如果需要一次更新多个参数,这个方法效率更高 +YCDownloader.updateByConfiguration(Configuration); +``` + +## Important classes + +**YCDownloader**: [`com.lyc.downloader.YCDownloader`](https://github.com/SirLYC/YC-Downloader/blob/master/downloader/src/main/java/com/lyc/downloader/YCDownloader.java) + +导出API。 + +**DownloadListener**: [`com.lyc.downloader.DownloadListener`](https://github.com/SirLYC/YC-Downloader/blob/master/downloader/src/main/java/com/lyc/downloader/DownloadListener.java) + +监听进度更新。**所有的回调方法都在主线程调用。** + +**DownloadTasksChangeListener**: [`com.lyc.downloader.DownloadTasksChangeListener`](https://github.com/SirLYC/YC-Downloader/blob/master/downloader/src/main/java/com/lyc/downloader/DownloadTasksChangeListener.java) + +当任务管理器的任务添加或移除时的回调,可以用来监听更新列表变化。**所有的回调方法都在主线程调用。** + +**SubmitListener**: [`com.lyc.downloader.SubmitListener`](https://github.com/SirLYC/YC-Downloader/blob/master/downloader/src/main/java/com/lyc/downloader/SubmitListener.java) + +通知提交任务成功或失败。 **所有的回调方法都在主线程调用。** + +**DownloadInfo**: [`com.lyc.downloader.db.DownloadInfo`](https://github.com/SirLYC/YC-Downloader/blob/master/downloader/src/main/java/com/lyc/downloader/db/DownloadInfo.java) + +数据库实体类,也是 `Parcelable`类型,用于多进程通信。 + +**Configuration**: [`com.lyc.downloader.Configuration`](https://github.com/SirLYC/YC-Downloader/blob/master/downloader/src/main/java/com/lyc/downloader/Configuration.java) + +一个不可变类型的class,定义参数。 + +## Permissions + +```xml + + + + + +``` + + +## Licence +``` +MIT License + +Copyright (c) 2019 Liu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +``` diff --git a/README.md b/README.md index a3942b0..2287e2e 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ [![](https://jitpack.io/v/SirLYC/YC-Downloader.svg)](https://jitpack.io/#SirLYC/YC-Downloader) +[中文文档](https://github.com/SirLYC/YC-Downloader/blob/master/README-zh.md) + A multi-thread, multi-task and multi-process downloader. It supports HTTP, download speed limit ## Features @@ -13,10 +15,11 @@ A multi-thread, multi-task and multi-process downloader. It supports HTTP, downl - [x] message control to avoid ui frame drops - [x] multi-process support - [x] download speed limit +- [x] auto-retry(connect and download) - [ ] other protocol download maybe... -## Run -**`app` module** +## Project +**`sample` module** A simple apk instance which uses download library. @@ -88,7 +91,7 @@ class App : Application() { // Decided by service in your manifest; // If both remote and local services are defined in your manifest, // remote one will be selected; - .setMultiProcess(true) + .setMultiProcess(false) // If allow download. Default true; .setAllowDownload(true) // If avoid frame drop. Default true; @@ -97,8 +100,9 @@ class App : Application() { .setMaxRunningTask(4) // Send progress update message to main thread interval time in nano. Default 333ms; .setSendMessageIntervalNanos(TimeUnit.MILLISECONDS.toNanos(333)) - // Speed limit. If <= 0, no limit; - .setSpeedLimit(1024) + // Speed limit(bytes/s). If <= 0, no limit; +// .setSpeedLimit(2048 * 1024) + .setSpeedLimit(0) .build() YCDownloader.install(this, config) @@ -110,7 +114,9 @@ class App : Application() { } ``` -Then Just learn apis! +## Proguard + +`Proguard` is already defined in the library, you don't have to specify for this library. ## Main API @@ -159,6 +165,9 @@ YCDownloader.queryFinishedDownloadInfoList(); ``` **Configuration** + +You can change configurations when downloader is running.These methods are safe to call in any thread. + ``` java // limit your running task to 4 YCDownloader.setMaxRunningTask(4); @@ -188,11 +197,15 @@ Export main apis. **DownloadListener**: [`com.lyc.downloader.DownloadListener`](https://github.com/SirLYC/YC-Downloader/blob/master/downloader/src/main/java/com/lyc/downloader/DownloadListener.java) -Callback of the download progress and state change of every downloadTask. +Callback of the download progress and state change of every downloadTask. **All methods are called in main thread.** **DownloadTasksChangeListener**: [`com.lyc.downloader.DownloadTasksChangeListener`](https://github.com/SirLYC/YC-Downloader/blob/master/downloader/src/main/java/com/lyc/downloader/DownloadTasksChangeListener.java) -Callback of the change in downloadTasks: created or removed. It's a good feature to implement a function like eventBus. +Callback of the change in downloadTasks: created or removed. It's a good feature to implement a function like eventBus. **All methods are called in main thread.** + +**SubmitListener**: [`com.lyc.downloader.SubmitListener`](https://github.com/SirLYC/YC-Downloader/blob/master/downloader/src/main/java/com/lyc/downloader/SubmitListener.java) + +Notify task submit state: success or fail. **All methods are called in main thread.** **DownloadInfo**: [`com.lyc.downloader.db.DownloadInfo`](https://github.com/SirLYC/YC-Downloader/blob/master/downloader/src/main/java/com/lyc/downloader/db/DownloadInfo.java) diff --git a/config.gradle b/config.gradle index 2bbdaec..45b7071 100644 --- a/config.gradle +++ b/config.gradle @@ -7,7 +7,7 @@ ext { 'targetSdkVersion' : 28, 'minSdkVersion' : 19, 'versionCode' : 1, - 'versionName' : '0.6.2-beta' + 'versionName' : '0.7.0-beta' ] deps = [ 'kotlin-stdlib' : "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version", diff --git a/downloader/build.gradle b/downloader/build.gradle index 8fb598a..1712af0 100644 --- a/downloader/build.gradle +++ b/downloader/build.gradle @@ -11,6 +11,7 @@ android { versionCode buildInfo['versionCode'] versionName buildInfo['versionName'] testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles 'proguard-rules.pro' } buildTypes { diff --git a/downloader/proguard-rules.pro b/downloader/proguard-rules.pro index f1b4245..0606db7 100644 --- a/downloader/proguard-rules.pro +++ b/downloader/proguard-rules.pro @@ -1,21 +1,70 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile +-optimizationpasses 5 +-dontusemixedcaseclassnames +-keepattributes *Annotation* +-keepattributes Signature + +-keep public class * extends android.app.Activity +-keep public class * extends android.app.Application +-keep public class * extends android.support.multidex.MultiDexApplication +-keep public class * extends android.app.Service +-keep public class * extends android.content.BroadcastReceiver +-keep public class * extends android.content.ContentProvider +-keep public class * extends android.app.backup.BackupAgentHelper +-keep public class * extends android.preference.Preference +-keep public class * extends android.view.View +-keep class android.support.** {*;} + +-keep public class * extends android.support.v4.** +-keep public class * extends android.support.v7.** +-keep public class * extends android.support.annotation.** + +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +-keep class * implements android.os.Parcelable { + public static final android.os.Parcelable$Creator *; +} + +-keepclassmembers class * implements java.io.Serializable { + static final long serialVersionUID; + private static final java.io.ObjectStreamField[] serialPersistentFields; + private void writeObject(java.io.ObjectOutputStream); + private void readObject(java.io.ObjectInputStream); + java.lang.Object writeReplace(); + java.lang.Object readResolve(); +} + +-keep class **.R$* { + *; +} + +-keepclassmembers class **.R$* { + public static ; +} + +-assumenosideeffects class android.util.Log { + public static *** v(...); + public static *** d(...); + public static *** i(...); + public static *** w(...); +} + +-dontwarn androidx.** +-keep class androidx.** { *; } +-keep interface androidx.** { *; } + +-keep class okhttp3.* { *; } +-keep interface okhttp3.* { *; } +-dontwarn okhttp3. + +-keepclassmembers class * extends org.greenrobot.greendao.AbstractDao { +public static java.lang.String TABLENAME; +} + +-keep class **$Properties +-keep class com.lyc.downloader.db.**{*;} + +-keep public interface * extends android.os.IInterface {*;} +-keep public class * implements android.os.IInterface {*;} diff --git a/downloader/src/main/java/com/lyc/downloader/BaseServiceManager.java b/downloader/src/main/java/com/lyc/downloader/BaseServiceManager.java index 02a63d2..27aa702 100644 --- a/downloader/src/main/java/com/lyc/downloader/BaseServiceManager.java +++ b/downloader/src/main/java/com/lyc/downloader/BaseServiceManager.java @@ -17,7 +17,7 @@ /** * Created by Liu Yuchuan on 2019/5/19. */ -public abstract class BaseServiceManager implements DownloadController, DownloadInfoProvider { +abstract class BaseServiceManager implements DownloadController, DownloadInfoProvider { private static final int MAX_SUPPORT_TASK_COUNT = Runtime.getRuntime().availableProcessors() * 4; private static final long WAITING_TIME = TimeUnit.SECONDS.toNanos(6); final Context appContext; diff --git a/downloader/src/main/java/com/lyc/downloader/DownloadListenerDispatcher.java b/downloader/src/main/java/com/lyc/downloader/DownloadListenerDispatcher.java index fef6bb5..731cdfb 100644 --- a/downloader/src/main/java/com/lyc/downloader/DownloadListenerDispatcher.java +++ b/downloader/src/main/java/com/lyc/downloader/DownloadListenerDispatcher.java @@ -15,7 +15,7 @@ * @date 2019-05-10 * @email kevinliu.sir@qq.com */ -public class DownloadListenerDispatcher extends IDownloadCallback.Stub { +class DownloadListenerDispatcher extends IDownloadCallback.Stub { // if id == null: register for all id @SuppressLint("UseSparseArrays") private final Map> downloadListenerMap = new HashMap<>(); diff --git a/keys/keystore.properties b/keys/keystore.properties new file mode 100644 index 0000000..8e1d275 --- /dev/null +++ b/keys/keystore.properties @@ -0,0 +1,4 @@ +KEYSTORE_FILE=../keys/test.jks +KEYSTORE_PWD=123456 +KEY_ALIAS=test +KEY_PWD=123456 diff --git a/keys/test.jks b/keys/test.jks new file mode 100644 index 0000000000000000000000000000000000000000..6dfb6d5dd723c02a90fc7e16a33838fa79b6eaf1 GIT binary patch literal 2070 zcmV+x2r>S$tw%PYh^Hck{X-i z?%qfqE4FWur6I2*Enh9dc!g_(y=o#jTQ!yodbl0SO&~rO>@@K$P ze#GBAmXpuMoNX%8-@#A{=zhy&dj$Ld0tj%a2at$B+PB)zfE1^0ax9w(F4_ijgHVlI z2DpRl@Txtg6*TYJqbaTW8Qd-g687v}sO~Ct7F7B>?#kaa09dJF>~pSjo66wBf!Mhj zeKI=SXwMmDc=?c(l-(wA-QiDLgvpUt7W9y9r@(B}{9%N_5^+}$ce3$PIVC6a;AuQs zn#Ax8hE++2d0O#;Rt=yaxy{|%!$INL>5VV;H?;%x+F{H5WrzZ7w5e8BE$a~7=8K)md2Ef~u(AbK86r-eM73NZ2 z{nDbgTtHH#*N8-e5;xU~=#MurD$IDMLxU+c_UCc&@q}3QD_M_{I&ihLFS!+$Q;^-y znE7!){Gj%b*5@DzrhUjh)@qt;?C9q5FcBs0;+t}6Bt*aq?v#j%lO%n)8A|4S9s@3a z+n53yJAt-|OYqt{6o$Q&9XxB=XexR1s3uYRRdiHCFA`g;dieX%RE6sf(l4-(m4<g{PlFPY|1?*e!1;ix1*WPWjn*Ma;l_r{Bb_Y@Uhyg-?!fi z7tO|9BYZm61~(m0DUcQ`Sb)9AP3BRU!4Rq^QVtx;s$^slg=Ps>IE-unAbxiMBQczE znYUYOvsr3A;tG>mLxf;17G7edWh4XRY6FdL?@_2mme*`DOvOZK z;R`=Q=7o7C!UF%!@Q8jFFjt>r$Cub^V-`mP3U5>)_ z^T}-&DI-s+)=9x)eD6T@o@o>WNE5jlsgg-+kYN0$VCTh~&cCKuCmV?>{k-(S0fRRjYQ3t4qzXmw$3AWUg>Fdi2TF*z_c zGcYhSFg7(bS{Ds8G%z+YGcYqSHZ?R_FcvWsFcJm>RRjYQ3t4qzXmw$3AWUg>FoFRh zFbxI?Duzgg_YDC70R;d9f&mWzFoFRJ0)hbn0E3%~CBw9qD%du?5})c0`7QC?E%K>? zy(GA!biTFPjwpi4E9G^uvb)mdQ4IV~-Q|9raa3oe+2^wc+P{qS7CKAv)39 zxY62_F9~}M?4yeeF<0HWGMz9y{;Xec%z1Z+vStffFDg5aU9hrPp!MxT1UUNM=D_I0 z=Ou(vFi6!wLm^SsZ)hyn)*7R+12pALsv4UZGXwoy7k)UE`#Cx^D`ZiA4_cG0V-mLl z+~o)p`Exgq>x$=q8;iV(uJq2OzdAj^TKnNwWi&$3!?k=)e;}#3gG(`fgQ|A+Q%@=) z8HyDO&{jFv1*Q?kWyO=E>aT1`VN% zI2#XIU;{j_IsR>~fJ9G)ev({#NjGo}AWl6PPaoVfHh(_8{%hbwiixhAZCL^@C$$uH z_$K=MfO&xh$%B+R18q-zAgJ~}I z+sH^hY%Eii0eVv3%xE8Pb~qRbw_$)EXa;XGm#X3?5y3fd)%eX8pz>>S& zc!L*iRE0y1+lIVBzmzWv+26M=*_m513DPisONf`G7U51+TLqY_w}LtX0-e4 literal 0 HcmV?d00001 diff --git a/sample/build.gradle b/sample/build.gradle index c30b40a..aafde7a 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -12,9 +12,25 @@ android { versionName buildInfo['versionName'] testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } + + signingConfigs { + release { + def signConfig = rootProject.file('keys/keystore.properties') + if (signConfig.exists()) { + Properties props = new Properties() + props.load(new FileInputStream(signConfig)) + storeFile file(props['KEYSTORE_FILE']) + storePassword props['KEYSTORE_PWD'] + keyAlias props['KEY_ALIAS'] + keyPassword props['KEY_PWD'] + } + } + } + buildTypes { release { - minifyEnabled false + minifyEnabled true + signingConfig signingConfigs.release proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } diff --git a/sample/proguard-rules.pro b/sample/proguard-rules.pro index f1b4245..d2b2b3d 100644 --- a/sample/proguard-rules.pro +++ b/sample/proguard-rules.pro @@ -19,3 +19,91 @@ # If you keep the line number information, uncomment this to # hide the original source file name. #-renamesourcefileattribute SourceFile +-optimizationpasses 5 +-dontusemixedcaseclassnames +-keepattributes *Annotation* +-keepattributes Signature + +-keep public class * extends android.app.Activity +-keep public class * extends android.app.Application +-keep public class * extends android.support.multidex.MultiDexApplication +-keep public class * extends android.app.Service +-keep public class * extends android.content.BroadcastReceiver +-keep public class * extends android.content.ContentProvider +-keep public class * extends android.app.backup.BackupAgentHelper +-keep public class * extends android.preference.Preference +-keep public class * extends android.view.View +-keep class android.support.** {*;} + +-keep public class * extends android.support.v4.** +-keep public class * extends android.support.v7.** +-keep public class * extends android.support.annotation.** + +-keepclassmembers class * extends android.app.Activity{ + public void *(android.view.View); +} + +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +-keep public class * extends android.view.View{ + *** get*(); + void set*(***); + public (android.content.Context); + public (android.content.Context, android.util.AttributeSet); + public (android.content.Context, android.util.AttributeSet, int); +} +-keepclasseswithmembers class * { + public (android.content.Context, android.util.AttributeSet); + public (android.content.Context, android.util.AttributeSet, int); +} + +-keep class * implements android.os.Parcelable { + public static final android.os.Parcelable$Creator *; +} + +-keepclassmembers class * implements java.io.Serializable { + static final long serialVersionUID; + private static final java.io.ObjectStreamField[] serialPersistentFields; + private void writeObject(java.io.ObjectOutputStream); + private void readObject(java.io.ObjectInputStream); + java.lang.Object writeReplace(); + java.lang.Object readResolve(); +} + +-keep class **.R$* { + *; +} + +-keepclassmembers class **.R$* { + public static ; +} + +-keepclassmembers class * { + void *(**On*Event); + void *(**On*Listener); +} + +-keep public class * extends android.view.View{ + *** get*(); + void set*(***); + public (android.content.Context); + public (android.content.Context, android.util.AttributeSet); + public (android.content.Context, android.util.AttributeSet, int); +} + +-assumenosideeffects class android.util.Log { + public static *** v(...); + public static *** d(...); + public static *** i(...); + public static *** w(...); +} + +-dontwarn com.google.android.material.** +-keep class com.google.android.material.** { *; } + +-dontwarn androidx.** +-keep class androidx.** { *; } +-keep interface androidx.** { *; } diff --git a/sample/src/main/java/com/lyc/yuchuan_downloader/App.kt b/sample/src/main/java/com/lyc/yuchuan_downloader/App.kt index 8a1593a..9e16892 100644 --- a/sample/src/main/java/com/lyc/yuchuan_downloader/App.kt +++ b/sample/src/main/java/com/lyc/yuchuan_downloader/App.kt @@ -27,8 +27,9 @@ class App : Application() { .setMaxRunningTask(4) // Send progress update message to main thread interval time in nano. Default 333ms; .setSendMessageIntervalNanos(TimeUnit.MILLISECONDS.toNanos(333)) - // Speed limit. If <= 0, no limit; - .setSpeedLimit(1024) + // Speed limit(bytes/s). If <= 0, no limit; +// .setSpeedLimit(2048 * 1024) + .setSpeedLimit(0) .build() YCDownloader.install(this, config)