diff --git a/Aria/src/main/java/com/arialyy/aria/core/WidgetLiftManager.java b/Aria/src/main/java/com/arialyy/aria/core/WidgetLiftManager.java index f19b5ab6..1ab43e76 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/WidgetLiftManager.java +++ b/Aria/src/main/java/com/arialyy/aria/core/WidgetLiftManager.java @@ -73,8 +73,16 @@ final class WidgetLiftManager { /** * 处理对话框取消或dismiss + * + * @return true 设置了dialog的销毁事件。false 没有设置dialog的销毁事件 */ boolean handleDialogLift(Dialog dialog) { + if (dialog == null) { + ALog.w(TAG, + "dialog 为空,没有设置自动销毁事件,为了防止内存泄露,请在dismiss方法中调用Aria.download(this).unRegister();来注销事件\n" + + "如果你使用的是DialogFragment,那么你需要在onDestroy()中进行销毁Aria事件操作"); + return false; + } try { Field dismissField = CommonUtil.getField(dialog.getClass(), "mDismissMessage"); Message dismissMsg = (Message) dismissField.get(dialog); diff --git a/Aria/src/main/java/com/arialyy/aria/core/common/ProxyHelper.java b/Aria/src/main/java/com/arialyy/aria/core/common/ProxyHelper.java index 780f262b..ff9c0ea8 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/common/ProxyHelper.java +++ b/Aria/src/main/java/com/arialyy/aria/core/common/ProxyHelper.java @@ -75,50 +75,23 @@ public class ProxyHelper { return result; } result = new HashSet<>(); - try { - if (getClass().getClassLoader() - .loadClass(className.concat(TaskEnum.DOWNLOAD_GROUP.proxySuffix)) - != null) { - result.add(PROXY_TYPE_DOWNLOAD_GROUP); - } - } catch (ClassNotFoundException e) { - //e.printStackTrace(); + if (checkProxyExist(className, TaskEnum.DOWNLOAD_GROUP.proxySuffix)) { + result.add(PROXY_TYPE_DOWNLOAD_GROUP); } - try { - if (getClass().getClassLoader().loadClass(className.concat(TaskEnum.DOWNLOAD.proxySuffix)) - != null) { - result.add(PROXY_TYPE_DOWNLOAD); - } - } catch (ClassNotFoundException e) { - //e.printStackTrace(); + if (checkProxyExist(className, TaskEnum.DOWNLOAD.proxySuffix)) { + result.add(PROXY_TYPE_DOWNLOAD); } - try { - if (getClass().getClassLoader().loadClass(className.concat(TaskEnum.UPLOAD.proxySuffix)) - != null) { - result.add(PROXY_TYPE_UPLOAD); - } - } catch (ClassNotFoundException e) { - //e.printStackTrace(); + if (checkProxyExist(className, TaskEnum.UPLOAD.proxySuffix)) { + result.add(PROXY_TYPE_UPLOAD); } - try { - if (getClass().getClassLoader().loadClass(className.concat(TaskEnum.M3U8_PEER.proxySuffix)) - != null) { - result.add(PROXY_TYPE_M3U8_PEER); - } - } catch (ClassNotFoundException e) { - //e.printStackTrace(); + if (checkProxyExist(className, TaskEnum.M3U8_PEER.proxySuffix)) { + result.add(PROXY_TYPE_M3U8_PEER); } - try { - if (getClass().getClassLoader() - .loadClass(className.concat(TaskEnum.DOWNLOAD_GROUP_SUB.proxySuffix)) - != null) { - result.add(PROXY_TYPE_DOWNLOAD_GROUP_SUB); - } - } catch (ClassNotFoundException e) { - //e.printStackTrace(); + if (checkProxyExist(className, TaskEnum.DOWNLOAD_GROUP_SUB.proxySuffix)) { + result.add(PROXY_TYPE_DOWNLOAD_GROUP_SUB); } if (!result.isEmpty()) { @@ -126,4 +99,20 @@ public class ProxyHelper { } return result; } + + private boolean checkProxyExist(String className, String proxySuffix) { + String clsName = className.concat(proxySuffix); + + try { + if (getClass().getClassLoader().loadClass(clsName) != null) { + return true; + } + if (Class.forName(clsName) != null) { + return true; + } + } catch (ClassNotFoundException e) { + //e.printStackTrace(); + } + return false; + } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8Option.java b/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8Option.java index eb921c8a..77e329a5 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8Option.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8Option.java @@ -33,12 +33,21 @@ public class M3U8Option extends BaseOption { private ITsMergeHandler mergeHandler; private IBandWidthUrlConverter bandWidthUrlConverter; private IKeyUrlConverter keyUrlConverter; + private boolean ignoreFailureTs = false; M3U8Option() { super(); ComponentUtil.getInstance().checkComponentExist(ComponentUtil.COMPONENT_TYPE_M3U8); } + /** + * 忽略下载失败的ts切片,即使有失败的切片,下载完成后也要合并所有切片,并进入complete回调 + */ + public OP ignoreFailureTs() { + this.ignoreFailureTs = true; + return (OP) this; + } + /** * 生成m3u8索引文件 * 注意:创建索引文件,{@link #merge(boolean)}方法设置与否都不再合并文件 diff --git a/DEV_LOG.md b/DEV_LOG.md index fb81df0b..7b92d358 100644 --- a/DEV_LOG.md +++ b/DEV_LOG.md @@ -2,6 +2,9 @@ + v_3.8 - 移除androidx和support的依赖,现在无论是哪个版本的appcompat包都可以使用本框架 - 修复一个在xml中使用fragment导致的内存泄漏问题 + - m3u8协议的key信息增加了`keyFormat`,`keyFormatVersion`字段 + - m3u8增加了`ignoreFailureTs`方法,忽略虾类失败的ts切片 + - 修复在dialogFragment的`onCreateDialog()`注册导致的注解不生效问题 + v_3.7.10 (2019/12/3) - fix bug https://github.com/AriaLyy/Aria/issues/543#issuecomment-559733124 - fix bug https://github.com/AriaLyy/Aria/issues/542 diff --git a/M3U8Component/src/main/java/com/arialyy/aria/m3u8/M3U8InfoThread.java b/M3U8Component/src/main/java/com/arialyy/aria/m3u8/M3U8InfoThread.java index 4c92af17..7d3ef2d4 100644 --- a/M3U8Component/src/main/java/com/arialyy/aria/m3u8/M3U8InfoThread.java +++ b/M3U8Component/src/main/java/com/arialyy/aria/m3u8/M3U8InfoThread.java @@ -255,6 +255,10 @@ final public class M3U8InfoThread implements Runnable { m3U8Entity.keyUrl) + ".key"; } else if (param.startsWith("IV")) { m3U8Entity.iv = param.split("=")[1]; + }else if (param.startsWith("KEYFORMAT")){ + m3U8Entity.keyFormat = param.split("=")[1]; + }else if (param.startsWith("KEYFORMATVERSIONS")){ + m3U8Entity.keyFormatVersion = param.split("=")[1]; } } downloadKey(m3U8Entity); diff --git a/M3U8Component/src/main/java/com/arialyy/aria/m3u8/M3U8TaskOption.java b/M3U8Component/src/main/java/com/arialyy/aria/m3u8/M3U8TaskOption.java index 5e9df9fe..b6c35052 100644 --- a/M3U8Component/src/main/java/com/arialyy/aria/m3u8/M3U8TaskOption.java +++ b/M3U8Component/src/main/java/com/arialyy/aria/m3u8/M3U8TaskOption.java @@ -109,6 +109,20 @@ public class M3U8TaskOption implements ITaskOption { */ private SoftReference keyUrlConverter; + /** + * 忽略下载失败的ts切片。 + * true:即使有失败的切片,下载完成后也要合并所有切片,并进入complete回调 + */ + private boolean ignoreFailureTs = false; + + public boolean isIgnoreFailureTs() { + return ignoreFailureTs; + } + + public void setIgnoreFailureTs(boolean ignoreFailureTs) { + this.ignoreFailureTs = ignoreFailureTs; + } + public IKeyUrlConverter getKeyUrlConverter() { return keyUrlConverter == null ? null : keyUrlConverter.get(); } diff --git a/M3U8Component/src/main/java/com/arialyy/aria/m3u8/vod/M3U8VodLoader.java b/M3U8Component/src/main/java/com/arialyy/aria/m3u8/vod/M3U8VodLoader.java index 86a2ceb5..49024b45 100644 --- a/M3U8Component/src/main/java/com/arialyy/aria/m3u8/vod/M3U8VodLoader.java +++ b/M3U8Component/src/main/java/com/arialyy/aria/m3u8/vod/M3U8VodLoader.java @@ -221,9 +221,9 @@ public class M3U8VodLoader extends BaseM3U8Loader { } } mManager.updateStateCount(); - if (mCompleteNum <= 0){ + if (mCompleteNum <= 0) { mListener.onStart(0); - }else { + } else { int percent = mCompleteNum * 100 / mRecord.threadRecords.size(); mListener.onResume(percent); } @@ -570,9 +570,9 @@ public class M3U8VodLoader extends BaseM3U8Loader { ALog.d(TAG, String.format("vod任务【%s】完成", mTempFile.getName())); if (mM3U8Option.isGenerateIndexFile()) { - if (generateIndexFile(false)){ + if (generateIndexFile(false)) { listener.onComplete(); - }else { + } else { listener.onFail(false, new TaskException(TAG, "创建索引文件失败")); } } else if (mM3U8Option.isMergeFile()) { @@ -621,7 +621,11 @@ public class M3U8VodLoader extends BaseM3U8Loader { } @Override public boolean isComplete() { - return mCompleteNum == taskRecord.threadRecords.size() && !isJump; + if (mM3U8Option.isIgnoreFailureTs()) { + return mCompleteNum + failNum >= taskRecord.threadRecords.size() && !isJump; + } else { + return mCompleteNum == taskRecord.threadRecords.size() && !isJump; + } } @Override public long getCurrentProgress() { diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/download/M3U8Entity.java b/PublicComponent/src/main/java/com/arialyy/aria/core/download/M3U8Entity.java index 2a04816f..d024cb43 100644 --- a/PublicComponent/src/main/java/com/arialyy/aria/core/download/M3U8Entity.java +++ b/PublicComponent/src/main/java/com/arialyy/aria/core/download/M3U8Entity.java @@ -21,6 +21,7 @@ import android.text.TextUtils; import com.arialyy.aria.core.TaskRecord; import com.arialyy.aria.core.ThreadRecord; import com.arialyy.aria.orm.DbEntity; +import com.arialyy.aria.orm.annotation.Default; import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.DbDataHelper; import java.io.File; @@ -78,6 +79,33 @@ public class M3U8Entity extends DbEntity implements Parcelable { */ public String iv; + /** + * key的格式,可能为空 + */ + public String keyFormat; + + /** + * key的格式版本,默认为1,如果是多个版本,使用"/"分隔,如:"1", "1/2", or "1/2/5" + */ + @Default("1") + public String keyFormatVersion = "1"; + + public String getKeyFormat() { + return keyFormat; + } + + public void setKeyFormat(String keyFormat) { + this.keyFormat = keyFormat; + } + + public String getKeyFormatVersion() { + return keyFormatVersion; + } + + public void setKeyFormatVersion(String keyFormatVersion) { + this.keyFormatVersion = keyFormatVersion; + } + public String getKeyPath() { return keyPath; } 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 495a39c0..0afb5956 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 @@ -50,7 +50,7 @@ class KotlinDownloadActivity : BaseActivity() { private var mUrl: String? = null private var mFilePath: String? = null private var mModule: HttpDownloadModule? = null - private val mTaskId: Long = -1 + private var mTaskId: Long = -1 internal var receiver: BroadcastReceiver = object : BroadcastReceiver() { override fun onReceive( @@ -104,7 +104,7 @@ class KotlinDownloadActivity : BaseActivity() { .get(HttpDownloadModule::class.java) mModule!!.getHttpDownloadInfo(this) .observe(this, Observer { entity -> - if (entity == null || entity.id < 0) { + if (entity == null) { return@Observer } if (entity.state == IEntity.STATE_STOP) { @@ -286,14 +286,21 @@ class KotlinDownloadActivity : BaseActivity() { } private fun startD() { - Aria.download(this) - .load(mUrl!!) - //.addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3") - //.addHeader("Accept-Encoding", "gzip, deflate") - //.addHeader("DNT", "1") - //.addHeader("Cookie", "BAIDUID=648E5FF020CC69E8DD6F492D1068AAA9:FG=1; BIDUPSID=648E5FF020CC69E8DD6F492D1068AAA9; PSTM=1519099573; BD_UPN=12314753; locale=zh; BDSVRTM=0") - .setFilePath(mFilePath!!, true) - .create() + if (mTaskId == -1L) { + + mTaskId = Aria.download(this) + .load(mUrl!!) + //.addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3") + //.addHeader("Accept-Encoding", "gzip, deflate") + //.addHeader("DNT", "1") + //.addHeader("Cookie", "BAIDUID=648E5FF020CC69E8DD6F492D1068AAA9:FG=1; BIDUPSID=648E5FF020CC69E8DD6F492D1068AAA9; PSTM=1519099573; BD_UPN=12314753; locale=zh; BDSVRTM=0") + .setFilePath(mFilePath!!, true) + .create() + } else { + Aria.download(this) + .load(mTaskId) + .resume() + } } override fun onStop() { diff --git a/build.gradle b/build.gradle index 72db2aac..42116f03 100644 --- a/build.gradle +++ b/build.gradle @@ -45,7 +45,7 @@ task clean(type: Delete) { ext { versionCode = 380 - versionName = '3.7.10' + versionName = '3.8_pre_1' userOrg = 'arialyy' groupId = 'com.arialyy.aria' publishVersion = versionName