修复转换器可能出现的内存泄漏

v3.6.6
laoyuyu 6 years ago
parent ae3d24f471
commit 060b1f138e
  1. 6
      Aria/src/main/java/com/arialyy/aria/core/common/ftp/IFtpUploadInterceptor.java
  2. 3
      Aria/src/main/java/com/arialyy/aria/core/download/DNormalConfigHandler.java
  3. 53
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadEntity.java
  4. 7
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpFileInfoThread.java
  5. 6
      Aria/src/main/java/com/arialyy/aria/core/download/m3u8/IBandWidthUrlConverter.java
  6. 6
      Aria/src/main/java/com/arialyy/aria/core/download/m3u8/ILiveTsUrlConverter.java
  7. 6
      Aria/src/main/java/com/arialyy/aria/core/download/m3u8/ITsMergeHandler.java
  8. 6
      Aria/src/main/java/com/arialyy/aria/core/download/m3u8/IVodTsUrlConverter.java
  9. 21
      Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8Delegate.java
  10. 109
      Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8Entity.java
  11. 9
      Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8InfoThread.java
  12. 3
      Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8LiveLoader.java
  13. 4
      Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8LiveUtil.java
  14. 13
      Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8TaskConfig.java
  15. 63
      Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8VodDelegate.java
  16. 13
      Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8VodLoader.java
  17. 3
      Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8VodUtil.java
  18. 6
      Aria/src/main/java/com/arialyy/aria/core/inf/IHttpFileLenAdapter.java
  19. 5
      Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpFileInfoThread.java
  20. 2
      Aria/src/main/java/com/arialyy/aria/orm/DBConfig.java
  21. 2
      Aria/src/main/java/com/arialyy/aria/orm/SqlHelper.java
  22. 2
      build.gradle

@ -41,7 +41,7 @@ import java.util.List;
*
* </pre>
*/
public interface IFtpUploadInterceptor {
public class IFtpUploadInterceptor {
/**
* 处理拦截事件
@ -49,5 +49,7 @@ public interface IFtpUploadInterceptor {
* @param entity 上传信息实体
* @param fileList ftp服务器端remotePath下的文件列表
*/
FtpInterceptHandler onIntercept(UploadEntity entity, List<String> fileList);
public FtpInterceptHandler onIntercept(UploadEntity entity, List<String> fileList) {
return null;
}
}

@ -118,7 +118,8 @@ class DNormalConfigHandler<TARGET extends AbsDTarget> implements IConfigHandler
wrapper.asM3U8().getBandWidth()));
if (wrapper.getRequestType() == ITaskWrapper.M3U8_VOD) {
if (mEntity.getFileSize() == 0) {
ALog.w(TAG, "由于m3u8协议的特殊性质,无法获取到正确到文件长度,因此你需要自行设置文件大小:asM3U8().setFileSize(xxx)");
ALog.w(TAG,
"由于m3u8协议的特殊性质,无法有效快速获取到正确到文件长度,如果你需要显示文件中长度,你需要自行设置文件长度:.asM3U8().asVod().setFileSize(xxx)");
}
} else if (wrapper.getRequestType() == ITaskWrapper.M3U8_LIVE) {
if (file.exists()) {

@ -19,9 +19,13 @@ package com.arialyy.aria.core.download;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import com.arialyy.aria.core.download.m3u8.M3U8Entity;
import com.arialyy.aria.core.inf.AbsNormalEntity;
import com.arialyy.aria.core.inf.AbsTaskWrapper;
import com.arialyy.aria.orm.DbEntity;
import com.arialyy.aria.orm.annotation.Ignore;
import com.arialyy.aria.orm.annotation.Unique;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil;
/**
@ -52,6 +56,27 @@ public class DownloadEntity extends AbsNormalEntity implements Parcelable {
*/
private String serverFileName;
@Ignore
private M3U8Entity m3U8Entity;
public M3U8Entity getM3U8Entity() {
if (TextUtils.isEmpty(downloadPath)) {
ALog.e("DownloadEntity", "文件保存路径为空,获取m3u8实体之前需要设置文件保存路径");
return null;
}
if (m3U8Entity == null) {
m3U8Entity = DbEntity.findFirst(M3U8Entity.class, "filePath=?", downloadPath);
}
if (m3U8Entity == null) {
m3U8Entity = new M3U8Entity();
m3U8Entity.setFilePath(downloadPath);
m3U8Entity.setPeerIndex(0);
m3U8Entity.insert();
}
return m3U8Entity;
}
@Override public String getKey() {
return getUrl();
}
@ -124,19 +149,6 @@ public class DownloadEntity extends AbsNormalEntity implements Parcelable {
return (DownloadEntity) super.clone();
}
@Override public int describeContents() {
return 0;
}
@Override public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeString(this.downloadPath);
dest.writeString(this.groupHash);
dest.writeString(this.md5Code);
dest.writeString(this.disposition);
dest.writeString(this.serverFileName);
}
@Override public String toString() {
return "DownloadEntity{"
+ "downloadPath='"
@ -160,6 +172,20 @@ public class DownloadEntity extends AbsNormalEntity implements Parcelable {
+ '}';
}
@Override public int describeContents() {
return 0;
}
@Override public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeString(this.downloadPath);
dest.writeString(this.groupHash);
dest.writeString(this.md5Code);
dest.writeString(this.disposition);
dest.writeString(this.serverFileName);
dest.writeParcelable(this.m3U8Entity, flags);
}
protected DownloadEntity(Parcel in) {
super(in);
this.downloadPath = in.readString();
@ -167,6 +193,7 @@ public class DownloadEntity extends AbsNormalEntity implements Parcelable {
this.md5Code = in.readString();
this.disposition = in.readString();
this.serverFileName = in.readString();
this.m3U8Entity = in.readParcelable(M3U8Entity.class.getClassLoader());
}
public static final Creator<DownloadEntity> CREATOR = new Creator<DownloadEntity>() {

@ -90,11 +90,6 @@ public class HttpFileInfoThread implements Runnable {
if (conn != null) {
conn.disconnect();
}
// 销毁文件长度适配器
IHttpFileLenAdapter lenAdapter = mTaskWrapper.asHttp().getFileLenAdapter();
if (lenAdapter != null && lenAdapter.getClass().isAnonymousClass()) {
mTaskWrapper.asHttp().setFileLenAdapter(null);
}
}
}
@ -336,7 +331,7 @@ public class HttpFileInfoThread implements Runnable {
}
}
private static class FileLenAdapter implements IHttpFileLenAdapter {
private static class FileLenAdapter extends IHttpFileLenAdapter {
@Override public long handleFileLen(Map<String, List<String>> headers) {
List<String> sLength = headers.get("Content-Length");

@ -19,7 +19,7 @@ package com.arialyy.aria.core.download.m3u8;
* M3U8 bandWidth 码率url转换器对于某些服务器返回的ts地址可以是相对地址也可能是处理过的
* 对于这种情况你需要使用url转换器将地址转换为可正常访问的http地址
*/
public interface IBandWidthUrlConverter {
public class IBandWidthUrlConverter {
/**
* 转换码率地址为可用的http地址对于某些服务器返回的切片信息有可能是相对地址也可能是处理过的
@ -28,5 +28,7 @@ public interface IBandWidthUrlConverter {
* @param bandWidthUrl 原始码率地址
* @return 可正常访问的http地址
*/
String convert(String bandWidthUrl);
public String convert(String bandWidthUrl) {
return null;
}
}

@ -19,7 +19,7 @@ package com.arialyy.aria.core.download.m3u8;
* M3U8 直播下载ts url转换器对于某些服务器返回的ts地址可以是相对地址也可能是处理过的
* 对于这种情况你需要使用url转换器将地址转换为可正常访问的http地址
*/
public interface ILiveTsUrlConverter {
public class ILiveTsUrlConverter {
/**
* 处理#EXTINF信息对于某些服务器返回的切片信息有可能是相对地址因此你需要自行转换为可下载http连接
@ -28,5 +28,7 @@ public interface ILiveTsUrlConverter {
* @param tsUrl ts文件下载地址
* @return 转换后的http地址
*/
String convert(String m3u8Url, String tsUrl);
public String convert(String m3u8Url, String tsUrl) {
return null;
}
}

@ -21,7 +21,7 @@ import java.util.List;
/**
* Ts文件合并处理如果你希望使用自行处理ts文件的合并你可以实现该接口
*/
public interface ITsMergeHandler {
public class ITsMergeHandler {
/**
* 合并ts文件
@ -30,5 +30,7 @@ public interface ITsMergeHandler {
* @param tsPath ts文件列表
* @return {@code true} 合并成功
*/
boolean merge(@Nullable M3U8KeyInfo keyInfo, List<String> tsPath);
public boolean merge(@Nullable M3U8KeyInfo keyInfo, List<String> tsPath) {
return false;
}
}

@ -21,7 +21,7 @@ import java.util.List;
* M3U8 点播文件下载ts url转换器对于某些服务器返回的ts地址可以是相对地址也可能是处理过的
* 对于这种情况你需要使用url转换器将地址转换为可正常访问的http地址
*/
public interface IVodTsUrlConverter {
public class IVodTsUrlConverter {
/**
* 处理#EXTINF信息对于某些服务器返回的切片信息有可能是相对地址因此你需要自行转换为可下载http连接
@ -30,5 +30,7 @@ public interface IVodTsUrlConverter {
* @param tsUrls ts文件下载地址列表
* @return 根据切片信息转换后的http连接列表如果你的切片信息是可以直接下载的http连接直接返回extInf便可
*/
List<String> convert(String m3u8Url, List<String> tsUrls);
public List<String> convert(String m3u8Url, List<String> tsUrls) {
return null;
}
}

@ -52,20 +52,6 @@ public class M3U8Delegate<TARGET extends AbsTarget> extends BaseDelegate<TARGET>
return this;
}
/**
* 由于m3u8协议的特殊性质无法获取到正确到文件长度因此你需要自行设置文件大小
*
* @param fileSize 文件长度
*/
public M3U8Delegate setFileSize(long fileSize) {
if (fileSize <= 0) {
ALog.e(TAG, "文件长度错误");
return this;
}
mTaskWrapper.getEntity().setFileSize(fileSize);
return this;
}
/**
* M3U8 ts 文件url转换器对于某些服务器返回的ts地址可以是相对地址也可能是处理过的
* 对于这种情况你需要使用url转换器将地址转换为可正常访问的http地址
@ -98,6 +84,13 @@ public class M3U8Delegate<TARGET extends AbsTarget> extends BaseDelegate<TARGET>
return this;
}
/**
* 处理点播文件的下载参数
*/
public M3U8VodDelegate<TARGET> asVod() {
return new M3U8VodDelegate<>(mTarget);
}
/**
* 处理直播类的下载
*/

@ -0,0 +1,109 @@
/*
* 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.m3u8;
import android.os.Parcel;
import android.os.Parcelable;
import com.arialyy.aria.orm.DbEntity;
/**
* M3U8实体信息
*/
public class M3U8Entity extends DbEntity implements Parcelable {
/**
* 文件保存路径
*/
private String filePath;
/**
* 当前peer的位置
*/
private int peerIndex;
/**
* peer总数
*/
private int peerNum;
/**
* 是否是直播true 直播
*/
private boolean isLive;
public boolean isLive() {
return isLive;
}
public void setLive(boolean live) {
isLive = live;
}
public String getFilePath() {
return filePath;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
public int getPeerIndex() {
return peerIndex;
}
public void setPeerIndex(int peerIndex) {
this.peerIndex = peerIndex;
}
public int getPeerNum() {
return peerNum;
}
public void setPeerNum(int peerNum) {
this.peerNum = peerNum;
}
public M3U8Entity() {
}
@Override public int describeContents() {
return 0;
}
@Override public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.filePath);
dest.writeInt(this.peerIndex);
dest.writeInt(this.peerNum);
dest.writeByte(this.isLive ? (byte) 1 : (byte) 0);
}
protected M3U8Entity(Parcel in) {
this.filePath = in.readString();
this.peerIndex = in.readInt();
this.peerNum = in.readInt();
this.isLive = in.readByte() != 0;
}
public static final Creator<M3U8Entity> CREATOR = new Creator<M3U8Entity>() {
@Override public M3U8Entity createFromParcel(Parcel source) {
return new M3U8Entity(source);
}
@Override public M3U8Entity[] newArray(int size) {
return new M3U8Entity[size];
}
};
}

@ -25,6 +25,7 @@ import com.arialyy.aria.core.common.http.HttpTaskConfig;
import com.arialyy.aria.core.download.DTaskWrapper;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.downloader.ConnectionHelp;
import com.arialyy.aria.core.inf.AbsTaskWrapper;
import com.arialyy.aria.core.inf.ITaskWrapper;
import com.arialyy.aria.exception.M3U8Exception;
import com.arialyy.aria.exception.TaskException;
@ -75,6 +76,7 @@ final class M3U8InfoThread implements Runnable {
AriaManager.getInstance(AriaManager.APP).getDownloadConfig().getConnectTimeOut();
onFileInfoCallback = callback;
mTaskDelegate = taskWrapper.asHttp();
mEntity.getM3U8Entity().setLive(mTaskWrapper.getRequestType() == AbsTaskWrapper.M3U8_LIVE);
}
@Override public void run() {
@ -145,6 +147,10 @@ final class M3U8InfoThread implements Runnable {
failDownload(String.format("获取M3U8下载地址列表失败,url: %s", mEntity.getUrl()), false);
return;
}
if (!isLive && mEntity.getM3U8Entity().getPeerNum() != 0) {
mEntity.getM3U8Entity().setPeerNum(extInf.size());
mEntity.getM3U8Entity().update();
}
CompleteInfo info = new CompleteInfo();
info.obj = extInf;
onFileInfoCallback.onComplete(mEntity.getKey(), info);
@ -247,9 +253,6 @@ final class M3U8InfoThread implements Runnable {
IBandWidthUrlConverter converter = mTaskWrapper.asM3U8().getBandWidthUrlConverter();
if (converter != null) {
bandWidthM3u8Url = converter.convert(bandWidthM3u8Url);
if (converter.getClass().isAnonymousClass()) {
mTaskWrapper.asM3U8().setBandWidthUrlConverter(null);
}
if (!bandWidthM3u8Url.startsWith("http")) {
failDownload(String.format("码率转换器转换后的url地址无效,转换后的url:%s", bandWidthM3u8Url), false);
return;

@ -173,9 +173,6 @@ public class M3U8LiveLoader extends BaseM3U8Loader {
boolean isSuccess;
if (mergeHandler != null) {
isSuccess = mergeHandler.merge(mTaskWrapper.asM3U8().getKeyInfo(), partPath);
if (mergeHandler.getClass().isAnonymousClass()) {
mTaskWrapper.asM3U8().setMergeHandler(null);
}
} else {
isSuccess = FileUtil.mergeFile(mEntity.getFilePath(), partPath);
}

@ -101,10 +101,6 @@ public class M3U8LiveUtil implements IUtil {
mListener.onFail(false, new M3U8Exception(TAG, "合并文件失败"));
}
}
ILiveTsUrlConverter converter = mWrapper.asM3U8().getLiveTsUrlConverter();
if (converter != null && converter.getClass().isAnonymousClass()) {
mWrapper.asM3U8().setLiveTsUrlConverter(null);
}
}
@Override public void start() {

@ -87,6 +87,19 @@ public class M3U8TaskConfig {
*/
private long liveUpdateInterval = 10 * 1000;
/**
* 同时下载的分片数量
*/
private int maxTsQueueNum = 4;
public int getMaxTsQueueNum() {
return maxTsQueueNum;
}
public void setMaxTsQueueNum(int maxTsQueueNum) {
this.maxTsQueueNum = maxTsQueueNum;
}
public long getLiveUpdateInterval() {
return liveUpdateInterval;
}

@ -0,0 +1,63 @@
/*
* 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.m3u8;
import com.arialyy.aria.core.common.BaseDelegate;
import com.arialyy.aria.core.download.DTaskWrapper;
import com.arialyy.aria.core.inf.AbsTarget;
import com.arialyy.aria.core.inf.AbsTaskWrapper;
import com.arialyy.aria.util.ALog;
/**
* m3u8点播文件参数设置
*/
public class M3U8VodDelegate<TARGET extends AbsTarget> extends BaseDelegate<TARGET> {
private DTaskWrapper mTaskWrapper;
M3U8VodDelegate(TARGET target) {
super(target);
mTaskWrapper = (DTaskWrapper) mTarget.getTaskWrapper();
mTaskWrapper.setRequestType(AbsTaskWrapper.M3U8_VOD);
}
/**
* 由于m3u8协议的特殊性质无法有效快速获取到正确到文件长度如果你需要显示文件中长度你需要自行设置文件长度
*
* @param fileSize 文件长度
*/
public M3U8VodDelegate setFileSize(long fileSize) {
if (fileSize <= 0) {
ALog.e(TAG, "文件长度错误");
return this;
}
mTaskWrapper.getEntity().setFileSize(fileSize);
return this;
}
/**
* 默认情况下对于同一点播文件的下载最多同时下载4个ts分片如果你希望增加或减少同时下载的ts分片数量可以使用该方法设置同时下载的ts分片数量
*
* @param num 同时下载的ts分片数量
*/
public M3U8VodDelegate setMaxTsQueueNum(int num) {
if (num < 1) {
ALog.e(TAG, "同时下载的分片数量不能小于1");
return this;
}
mTaskWrapper.asM3U8().setMaxTsQueueNum(num);
return this;
}
}

@ -48,13 +48,14 @@ public class M3U8VodLoader extends BaseM3U8Loader {
*/
private static final int EXEC_MAX_NUM = 4;
private Handler mStateHandler;
private ArrayBlockingQueue<Long> mFlagQueue = new ArrayBlockingQueue<>(EXEC_MAX_NUM);
private ArrayBlockingQueue<Long> mFlagQueue;
private VodStateManager mManager;
private ReentrantLock LOCK = new ReentrantLock();
private Condition mCondition = LOCK.newCondition();
M3U8VodLoader(IEventListener listener, DTaskWrapper wrapper) {
super(listener, wrapper);
mFlagQueue = new ArrayBlockingQueue<>(wrapper.asM3U8().getMaxTsQueueNum());
}
@Override protected IThreadState getStateManager(Looper looper) {
@ -84,7 +85,8 @@ public class M3U8VodLoader extends BaseM3U8Loader {
M3U8ThreadTask task = createThreadTask(cacheDir, tr);
getTaskList().put(tr.threadId, task);
mFlagQueue.offer(startThreadTask(task));
mEntity.getM3U8Entity().setPeerIndex(index);
mFlagQueue.offer(startThreadTask(task, index));
}
if (mFlagQueue.size() > 0) {
mCondition.await();
@ -122,9 +124,9 @@ public class M3U8VodLoader extends BaseM3U8Loader {
*
* @return 线程唯一id标志
*/
private long startThreadTask(M3U8ThreadTask task) {
private long startThreadTask(M3U8ThreadTask task, int peerIndex) {
ThreadTaskManager.getInstance().startThread(mTaskWrapper.getKey(), task);
return IdGenerator.getInstance().nextId();
return peerIndex;
}
/**
@ -304,9 +306,6 @@ public class M3U8VodLoader extends BaseM3U8Loader {
boolean isSuccess;
if (mergeHandler != null) {
isSuccess = mergeHandler.merge(mTaskWrapper.asM3U8().getKeyInfo(), partPath);
if (mergeHandler.getClass().isAnonymousClass()) {
mTaskWrapper.asM3U8().setMergeHandler(null);
}
} else {
isSuccess = FileUtil.mergeFile(mTaskRecord.filePath, partPath);
}

@ -103,9 +103,6 @@ public class M3U8VodUtil implements IUtil {
mUrls.addAll(
converter.convert(mWrapper.asM3U8().getBandWidthUrl(), (List<String>) info.obj));
}
if (converter.getClass().isAnonymousClass()) {
mWrapper.asM3U8().setVodUrlConverter(null);
}
} else {
mUrls.addAll((Collection<? extends String>) info.obj);
}

@ -23,7 +23,7 @@ import java.util.Map;
/**
* Http文件长度适配器
*/
public interface IHttpFileLenAdapter extends Serializable {
public class IHttpFileLenAdapter implements Serializable {
long serialVersionUID = 1L;
/**
@ -32,5 +32,7 @@ public interface IHttpFileLenAdapter extends Serializable {
* @param headers header参数{@link URLConnection#getHeaderFields()}
* @return 文件长度
*/
long handleFileLen(Map<String, List<String>> headers);
public long handleFileLen(Map<String, List<String>> headers) {
return 0;
}
}

@ -102,11 +102,6 @@ class FtpFileInfoThread extends AbsFtpInfoThread<UploadEntity, UTaskWrapper> {
} catch (IOException e) {
e.printStackTrace();
return false;
} finally {
IFtpUploadInterceptor interceptor = mTaskWrapper.asFtp().getUploadInterceptor();
if (interceptor != null && interceptor.getClass().isAnonymousClass()) {
mTaskWrapper.asFtp().setUploadInterceptor(null);
}
}
return true;

@ -37,7 +37,7 @@ class DBConfig {
static boolean DEBUG = false;
static Map<String, Class> mapping = new LinkedHashMap<>();
static String DB_NAME;
static int VERSION = 48;
static int VERSION = 49;
/**
* 是否将数据库保存在Sd卡{@code true}

@ -98,7 +98,7 @@ final class SqlHelper extends SQLiteOpenHelper {
handle314AriaUpdate(db);
} else if (oldVersion < 45) {
handle360AriaUpdate(db);
} else if (oldVersion < 48) {
} else if (oldVersion < 49) {
handle365Update(db);
} else {
handleDbUpdate(db, null, null);

@ -43,7 +43,7 @@ task clean(type: Delete) {
ext {
userOrg = 'arialyy'
groupId = 'com.arialyy.aria'
publishVersion = '3.6.5_beta_1'
publishVersion = '3.6.5_beta_2'
// publishVersion = '1.0.4' //FTP插件
repoName='maven'
desc = 'android 下载框架'

Loading…
Cancel
Save