laoyuyu 5 years ago
parent b0818537f2
commit b1bc4529c0
  1. 1
      AppFrame/src/main/java/com/arialyy/frame/base/BaseFragment.java
  2. 13
      Aria/src/main/java/com/arialyy/aria/core/command/AbsNormalCmd.java
  3. 12
      Aria/src/main/java/com/arialyy/aria/core/command/ICmd.java
  4. 4
      Aria/src/main/java/com/arialyy/aria/core/common/BaseListener.java
  5. 2
      Aria/src/main/java/com/arialyy/aria/core/common/http/HttpTaskConfig.java
  6. 14
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupListener.java
  7. 8
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java
  8. 16
      Aria/src/main/java/com/arialyy/aria/core/download/group/AbsGroupUtil.java
  9. 6
      Aria/src/main/java/com/arialyy/aria/core/download/group/ChildDownloadListener.java
  10. 12
      Aria/src/main/java/com/arialyy/aria/core/download/group/SimpleSchedulers.java
  11. 35
      Aria/src/main/java/com/arialyy/aria/core/download/group/SimpleSubQueue.java
  12. 9
      Aria/src/main/java/com/arialyy/aria/core/download/group/SubDLoadUtil.java
  13. 91
      Aria/src/main/java/com/arialyy/aria/core/inf/AbsTarget.java
  14. 2
      Aria/src/main/java/com/arialyy/aria/core/manager/ThreadTaskManager.java
  15. 73
      Aria/src/main/java/com/arialyy/aria/core/scheduler/AbsSchedulers.java
  16. 4
      Aria/src/main/java/com/arialyy/aria/core/scheduler/ISchedulers.java
  17. 6
      Aria/src/main/java/com/arialyy/aria/core/upload/UploadReceiver.java
  18. 7
      Aria/src/main/java/com/arialyy/aria/util/RecordUtil.java
  19. 2
      DEV_LOG.md
  20. 1
      app/build.gradle
  21. 46
      app/src/main/java/com/arialyy/simple/common/LoadingDialog.java
  22. 5
      app/src/main/java/com/arialyy/simple/core/download/SingleTaskActivity.java
  23. 2
      app/src/main/java/com/arialyy/simple/core/download/group/ChildHandleDialog.java
  24. 23
      app/src/main/java/com/arialyy/simple/core/download/group/DownloadGroupActivity.java
  25. 21
      app/src/main/java/com/arialyy/simple/core/download/m3u8/M3U8VodDLoadActivity.java
  26. 108
      app/src/main/java/com/arialyy/simple/core/download/m3u8/VideoPlayerFragment.java
  27. 20
      app/src/main/java/com/arialyy/simple/to/PeerIndex.java
  28. 5
      app/src/main/res/drawable/bg_loading.xml
  29. 8
      app/src/main/res/layout/activity_download_group.xml
  30. 19
      app/src/main/res/layout/dialog_loading.xml
  31. 5
      app/src/main/res/layout/fragment_video_player.xml
  32. BIN
      img/m3u8VodDownload.gif

@ -9,6 +9,7 @@ import com.arialyy.frame.core.AbsFragment;
public abstract class BaseFragment<VB extends ViewDataBinding> extends AbsFragment<VB> {
public int color;
@Override protected void dataCallback(int result, Object obj) {
}

@ -21,6 +21,7 @@ import com.arialyy.aria.core.download.DTaskWrapper;
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.inf.ITask;
import com.arialyy.aria.core.queue.DownloadGroupTaskQueue;
import com.arialyy.aria.core.queue.DownloadTaskQueue;
import com.arialyy.aria.core.queue.UploadTaskQueue;
@ -41,26 +42,26 @@ public abstract class AbsNormalCmd<T extends AbsTaskWrapper> extends AbsCmd<T> {
int taskType;
/**
* @param taskType 下载任务类型{@link ICmd#TASK_TYPE_DOWNLOAD}{@link ICmd#TASK_TYPE_DOWNLOAD_GROUP}{@link
* ICmd#TASK_TYPE_UPLOAD}
* @param taskType 下载任务类型{@link ITask#DOWNLOAD}{@link ITask#DOWNLOAD_GROUP}{@link
* ITask#UPLOAD}
*/
AbsNormalCmd(T entity, int taskType) {
this.taskType = taskType;
mTaskWrapper = entity;
TAG = CommonUtil.getClassName(this);
if (taskType == ICmd.TASK_TYPE_DOWNLOAD) {
if (taskType == ITask.DOWNLOAD) {
if (!(entity instanceof DTaskWrapper)) {
ALog.e(TAG, "任务类型错误,任务类型应该为ICM.TASK_TYPE_DOWNLOAD");
return;
}
mQueue = DownloadTaskQueue.getInstance();
} else if (taskType == ICmd.TASK_TYPE_DOWNLOAD_GROUP) {
} else if (taskType == ITask.DOWNLOAD_GROUP) {
if (!(entity instanceof DGTaskWrapper)) {
ALog.e(TAG, "任务类型错误,任务类型应该为ICM.TASK_TYPE_DOWNLOAD_GROUP");
return;
}
mQueue = DownloadGroupTaskQueue.getInstance();
} else if (taskType == ICmd.TASK_TYPE_UPLOAD) {
} else if (taskType == ITask.UPLOAD) {
if (!(entity instanceof UTaskWrapper)) {
ALog.e(TAG, "任务类型错误,任务类型应该为ICM.TASK_TYPE_UPLOAD");
return;
@ -70,7 +71,7 @@ public abstract class AbsNormalCmd<T extends AbsTaskWrapper> extends AbsCmd<T> {
ALog.e(TAG, "任务类型错误,任务类型应该为ICM.TASK_TYPE_DOWNLOAD、TASK_TYPE_DOWNLOAD_GROUP、TASK_TYPE_UPLOAD");
return;
}
isDownloadCmd = taskType < ICmd.TASK_TYPE_UPLOAD;
isDownloadCmd = taskType == ITask.DOWNLOAD || taskType == ITask.DOWNLOAD_GROUP;
}
/**

@ -20,18 +20,6 @@ package com.arialyy.aria.core.command;
*/
public interface ICmd {
/**
* 单任务下载任务
*/
int TASK_TYPE_DOWNLOAD = 0x01;
/**
* 任务组下载任务
*/
int TASK_TYPE_DOWNLOAD_GROUP = 0x02;
/**
* 上传任务
*/
int TASK_TYPE_UPLOAD = 0x10;
/**
* 执行命令

@ -38,12 +38,12 @@ public abstract class BaseListener<ENTITY extends AbsEntity, TASK_WRAPPER extend
TASK extends AbsTask<TASK_WRAPPER>>
implements IEventListener {
protected static String TAG;
private static final int RUN_SAVE_INTERVAL = 5 * 1000; //5s保存一次下载中的进度
protected static final int RUN_SAVE_INTERVAL = 5 * 1000; //5s保存一次下载中的进度
protected WeakReference<Handler> outHandler;
private long mLastLen; //上一次发送长度
private boolean isFirst = true;
private TASK mTask;
private long mLastSaveTime;
protected long mLastSaveTime;
protected ENTITY mEntity;
protected TASK_WRAPPER mTaskWrapper;
private boolean isConvertSpeed;

@ -86,7 +86,7 @@ public class HttpTaskConfig implements ITaskConfig {
private WeakReference<IHttpFileLenAdapter> fileLenAdapter;
public IHttpFileLenAdapter getFileLenAdapter() {
return fileLenAdapter.get();
return fileLenAdapter == null ? null : fileLenAdapter.get();
}
/**

@ -16,7 +16,6 @@
package com.arialyy.aria.core.download;
import android.os.Handler;
import com.arialyy.aria.core.common.BaseListener;
import com.arialyy.aria.core.common.RecordHandler;
import com.arialyy.aria.core.download.group.IDownloadGroupListener;
@ -46,6 +45,7 @@ class DownloadGroupListener
@Override
public void onSubPre(DownloadEntity subEntity) {
saveSubState(IEntity.STATE_PRE, subEntity);
sendInState2Target(ISchedulers.SUB_PRE, subEntity);
}
@ -56,23 +56,27 @@ class DownloadGroupListener
@Override
public void onSubStart(DownloadEntity subEntity) {
saveSubState(IEntity.STATE_RUNNING, subEntity);
sendInState2Target(ISchedulers.SUB_START, subEntity);
}
@Override
public void onSubStop(DownloadEntity subEntity) {
saveSubState(IEntity.STATE_STOP, subEntity);
saveCurrentLocation();
sendInState2Target(ISchedulers.SUB_STOP, subEntity);
}
@Override
public void onSubComplete(DownloadEntity subEntity) {
saveSubState(IEntity.STATE_COMPLETE, subEntity);
saveCurrentLocation();
sendInState2Target(ISchedulers.SUB_COMPLETE, subEntity);
}
@Override
public void onSubFail(DownloadEntity subEntity, BaseException e) {
saveSubState(IEntity.STATE_FAIL, subEntity);
saveCurrentLocation();
sendInState2Target(ISchedulers.SUB_FAIL, subEntity);
if (e != null) {
@ -83,12 +87,17 @@ class DownloadGroupListener
@Override
public void onSubCancel(DownloadEntity subEntity) {
saveSubState(IEntity.STATE_CANCEL, subEntity);
saveCurrentLocation();
sendInState2Target(ISchedulers.SUB_CANCEL, subEntity);
}
@Override
public void onSubRunning(DownloadEntity subEntity) {
if (System.currentTimeMillis() - mLastSaveTime >= RUN_SAVE_INTERVAL) {
saveSubState(IEntity.STATE_RUNNING, subEntity);
mLastSaveTime = System.currentTimeMillis();
}
sendInState2Target(ISchedulers.SUB_RUNNING, subEntity);
}
@ -102,7 +111,6 @@ class DownloadGroupListener
mSeedEntity.entity = subEntity;
outHandler.get().obtainMessage(state, ISchedulers.IS_SUB_TASK, 0, mSeedEntity).sendToTarget();
}
saveSubState(state, subEntity);
}
private void saveSubState(int state, DownloadEntity subEntity) {
@ -117,7 +125,7 @@ class DownloadGroupListener
subEntity.setConvertSpeed("0kb/s");
subEntity.setSpeed(0);
ALog.i(TAG, String.format("任务【%s】完成,将删除线程任务记录", mEntity.getKey()));
RecordUtil.delTaskRecord(subEntity.getKey(), RecordHandler.TYPE_DOWNLOAD, false, false);
RecordUtil.delTaskRecord(subEntity.getFilePath(), RecordHandler.TYPE_DOWNLOAD, false, false);
}
subEntity.update();
}

@ -21,12 +21,12 @@ import android.text.TextUtils;
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.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.ITask;
import com.arialyy.aria.core.inf.ReceiverType;
import com.arialyy.aria.core.scheduler.DownloadGroupSchedulers;
import com.arialyy.aria.core.scheduler.DownloadSchedulers;
@ -423,7 +423,7 @@ public class DownloadReceiver extends AbsReceiver {
public void stopAllTask() {
EventMsgUtil.getDefault().post(NormalCmdFactory.getInstance()
.createCmd(new DTaskWrapper(null), NormalCmdFactory.TASK_STOP_ALL,
ICmd.TASK_TYPE_DOWNLOAD));
ITask.DOWNLOAD));
}
/**
@ -434,7 +434,7 @@ public class DownloadReceiver extends AbsReceiver {
public void resumeAllTask() {
EventMsgUtil.getDefault().post(NormalCmdFactory.getInstance()
.createCmd(new DTaskWrapper(null), NormalCmdFactory.TASK_RESUME_ALL,
ICmd.TASK_TYPE_DOWNLOAD));
ITask.DOWNLOAD));
}
/**
@ -447,7 +447,7 @@ public class DownloadReceiver extends AbsReceiver {
final AriaManager ariaManager = AriaManager.getInstance(AriaManager.APP);
CancelAllCmd cancelCmd =
(CancelAllCmd) CommonUtil.createNormalCmd(new DTaskWrapper(null),
NormalCmdFactory.TASK_CANCEL_ALL, ICmd.TASK_TYPE_DOWNLOAD);
NormalCmdFactory.TASK_CANCEL_ALL, ITask.DOWNLOAD);
cancelCmd.removeFile = removeFile;
EventMsgUtil.getDefault().post(cancelCmd);

@ -50,7 +50,7 @@ public abstract class AbsGroupUtil implements IUtil, Runnable {
private boolean isStop = false, isCancel = false;
private Handler mScheduler;
private SimpleSubQueue mSubQueue = SimpleSubQueue.newInstance();
private Map<String, SubDownloadLoader> mExeLoader = new WeakHashMap<>();
private Map<String, SubDLoadUtil> mExeLoader = new WeakHashMap<>();
private Map<String, DTaskWrapper> mCache = new WeakHashMap<>();
DGTaskWrapper mGTWrapper;
GroupRunState mState;
@ -102,7 +102,7 @@ public abstract class AbsGroupUtil implements IUtil, Runnable {
if (!mState.isRunning) {
startTimer();
}
SubDownloadLoader d = getDownloader(url);
SubDLoadUtil d = getDownloader(url);
if (d != null && !d.isRunning()) {
mSubQueue.startTask(d);
}
@ -115,7 +115,7 @@ public abstract class AbsGroupUtil implements IUtil, Runnable {
*/
public void stopSubTask(String url) {
if (!checkSubTask(url, "停止")) return;
SubDownloadLoader d = getDownloader(url);
SubDLoadUtil d = getDownloader(url);
if (d != null && d.isRunning()) {
mSubQueue.stopTask(d);
}
@ -147,8 +147,8 @@ public abstract class AbsGroupUtil implements IUtil, Runnable {
*
* @param url 子任务下载地址
*/
private SubDownloadLoader getDownloader(String url) {
SubDownloadLoader d = mExeLoader.get(url);
private SubDLoadUtil getDownloader(String url) {
SubDLoadUtil d = mExeLoader.get(url);
if (d == null) {
return createAndStartSubLoader(mCache.get(url));
}
@ -266,7 +266,7 @@ public abstract class AbsGroupUtil implements IUtil, Runnable {
/**
* 创建并启动子任务下载器
*/
SubDownloadLoader createAndStartSubLoader(DTaskWrapper taskWrapper) {
SubDLoadUtil createAndStartSubLoader(DTaskWrapper taskWrapper) {
return createAndStartSubLoader(taskWrapper, true);
}
@ -275,8 +275,8 @@ public abstract class AbsGroupUtil implements IUtil, Runnable {
*
* @param needGetFileInfo {@code true} 需要获取文件信息{@code false} 不需要获取文件信息
*/
SubDownloadLoader createAndStartSubLoader(DTaskWrapper taskWrapper, boolean needGetFileInfo) {
SubDownloadLoader loader = new SubDownloadLoader(mScheduler, taskWrapper, needGetFileInfo);
SubDLoadUtil createAndStartSubLoader(DTaskWrapper taskWrapper, boolean needGetFileInfo) {
SubDLoadUtil loader = new SubDLoadUtil(mScheduler, taskWrapper, needGetFileInfo);
mExeLoader.put(loader.getKey(), loader);
mSubQueue.startTask(loader);
return loader;

@ -32,9 +32,9 @@ class ChildDownloadListener implements IDownloadListener {
private long lastSaveTime;
private long lastLen;
private Handler schedulers;
private SubDownloadLoader loader;
private SubDLoadUtil loader;
ChildDownloadListener(Handler schedulers, SubDownloadLoader loader) {
ChildDownloadListener(Handler schedulers, SubDLoadUtil loader) {
this.loader = loader;
this.schedulers = schedulers;
subEntity = loader.getEntity();
@ -140,7 +140,7 @@ class ChildDownloadListener implements IDownloadListener {
*
* @param state {@link ISchedulers}
*/
private void sendToTarget(int state, SubDownloadLoader util) {
private void sendToTarget(int state, SubDLoadUtil util) {
schedulers.obtainMessage(state, util).sendToTarget();
}
}

@ -20,6 +20,7 @@ import android.os.Message;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.config.Configuration;
import com.arialyy.aria.core.inf.AbsEntity;
import com.arialyy.aria.core.manager.ThreadTaskManager;
import com.arialyy.aria.core.scheduler.ISchedulers;
import com.arialyy.aria.exception.TaskException;
import com.arialyy.aria.util.ALog;
@ -47,7 +48,7 @@ class SimpleSchedulers implements ISchedulers {
}
@Override public boolean handleMessage(Message msg) {
SubDownloadLoader loader = (SubDownloadLoader) msg.obj;
SubDLoadUtil loader = (SubDLoadUtil) msg.obj;
switch (msg.what) {
case RUNNING:
mGState.listener.onSubRunning(loader.getEntity());
@ -78,7 +79,7 @@ class SimpleSchedulers implements ISchedulers {
* 2stopNum + failNum + completeNum + cacheNum == subSize则认为组合任务停止
* 3failNum == subSize只有全部的子任务都失败了才能任务组合任务失败
*/
private synchronized void handleFail(final SubDownloadLoader loader) {
private synchronized void handleFail(final SubDLoadUtil loader) {
Configuration config = Configuration.getInstance();
long interval = config.dGroupCfg.getSubReTryInterval();
@ -125,7 +126,7 @@ class SimpleSchedulers implements ISchedulers {
* 1所有的子任务已经停止则认为组合任务停止
* 2completeNum + failNum + stopNum = subSize则认为组合任务停止
*/
private synchronized void handleStop(SubDownloadLoader loader) {
private synchronized void handleStop(SubDLoadUtil loader) {
mGState.listener.onSubStop(loader.getEntity());
mGState.countStopNum(loader.getKey());
if (mGState.getStopNum() == mGState.getSubSize()
@ -150,8 +151,9 @@ class SimpleSchedulers implements ISchedulers {
* GroupRunState#getFailNum()}不为0则认为组合任务被停止
* 3只有有缓存的子任务则任务组合任务没有完成
*/
private synchronized void handleComplete(SubDownloadLoader loader) {
private synchronized void handleComplete(SubDLoadUtil loader) {
ALog.d(TAG, String.format("子任务【%s】完成", loader.getEntity().getFileName()));
ThreadTaskManager.getInstance().removeTaskThread(loader.getKey());
mGState.listener.onSubComplete(loader.getEntity());
mQueue.removeTaskFromExecQ(loader);
mGState.updateCompleteNum();
@ -177,7 +179,7 @@ class SimpleSchedulers implements ISchedulers {
if (mQueue.isStopAll()) {
return;
}
SubDownloadLoader next = mQueue.getNextTask();
SubDLoadUtil next = mQueue.getNextTask();
if (next != null) {
ALog.d(TAG, String.format("启动任务:%s", next.getEntity().getFileName()));
mQueue.startTask(next);

@ -28,16 +28,16 @@ import java.util.Set;
/**
* 组合任务队列该队列生命周期和{@link AbsGroupUtil}生命周期一致
*/
class SimpleSubQueue implements ISubQueue<SubDownloadLoader> {
class SimpleSubQueue implements ISubQueue<SubDLoadUtil> {
private static final String TAG = "SimpleSubQueue";
/**
* 缓存下载器
*/
private Map<String, SubDownloadLoader> mCache = new LinkedHashMap<>();
private Map<String, SubDLoadUtil> mCache = new LinkedHashMap<>();
/**
* 执行中的下载器
*/
private Map<String, SubDownloadLoader> mExec = new LinkedHashMap<>();
private Map<String, SubDLoadUtil> mExec = new LinkedHashMap<>();
/**
* 最大执行任务数
@ -57,7 +57,7 @@ class SimpleSubQueue implements ISubQueue<SubDownloadLoader> {
return new SimpleSubQueue();
}
Map<String, SubDownloadLoader> getExec() {
Map<String, SubDLoadUtil> getExec() {
return mExec;
}
@ -72,11 +72,11 @@ class SimpleSubQueue implements ISubQueue<SubDownloadLoader> {
return isStopAll;
}
@Override public void addTask(SubDownloadLoader fileer) {
@Override public void addTask(SubDLoadUtil fileer) {
mCache.put(fileer.getKey(), fileer);
}
@Override public void startTask(SubDownloadLoader fileer) {
@Override public void startTask(SubDLoadUtil fileer) {
if (mExec.size() < mExecSize) {
mCache.remove(fileer.getKey());
mExec.put(fileer.getKey(), fileer);
@ -88,7 +88,7 @@ class SimpleSubQueue implements ISubQueue<SubDownloadLoader> {
}
}
@Override public void stopTask(SubDownloadLoader fileer) {
@Override public void stopTask(SubDLoadUtil fileer) {
fileer.stop();
mExec.remove(fileer.getKey());
}
@ -98,7 +98,7 @@ class SimpleSubQueue implements ISubQueue<SubDownloadLoader> {
ALog.d(TAG, "停止组合任务");
Set<String> keys = mExec.keySet();
for (String key : keys) {
SubDownloadLoader loader = mExec.get(key);
SubDLoadUtil loader = mExec.get(key);
if (loader != null) {
ALog.d(TAG, String.format("停止子任务:%s", loader.getEntity().getFileName()));
loader.stop();
@ -122,7 +122,7 @@ class SimpleSubQueue implements ISubQueue<SubDownloadLoader> {
if (oldSize < num) { // 处理队列变小的情况,该情况下将停止队尾任务,并将这些任务添加到缓存队列中
if (mExec.size() > num) {
Set<String> keys = mExec.keySet();
List<SubDownloadLoader> caches = new ArrayList<>();
List<SubDLoadUtil> caches = new ArrayList<>();
int i = 0;
for (String key : keys) {
if (i > num) {
@ -130,20 +130,19 @@ class SimpleSubQueue implements ISubQueue<SubDownloadLoader> {
}
i++;
}
Collection<SubDownloadLoader> temp = mCache.values();
Collection<SubDLoadUtil> temp = mCache.values();
mCache.clear();
ALog.d(TAG, String.format("测试, cacheSize: %s", mCache.size()));
for (SubDownloadLoader cache : caches) {
for (SubDLoadUtil cache : caches) {
addTask(cache);
}
for (SubDownloadLoader t : temp) {
for (SubDLoadUtil t : temp) {
addTask(t);
}
}
} else { // 处理队列变大的情况,该情况下将增加任务
if (mExec.size() < num) {
for (int i = 0; i < diff; i++) {
SubDownloadLoader next = getNextTask();
SubDLoadUtil next = getNextTask();
if (next != null) {
startTask(next);
} else {
@ -154,7 +153,7 @@ class SimpleSubQueue implements ISubQueue<SubDownloadLoader> {
}
}
@Override public void removeTaskFromExecQ(SubDownloadLoader fileer) {
@Override public void removeTaskFromExecQ(SubDLoadUtil fileer) {
if (mExec.containsKey(fileer.getKey())) {
if (fileer.isRunning()) {
fileer.stop();
@ -163,7 +162,7 @@ class SimpleSubQueue implements ISubQueue<SubDownloadLoader> {
}
}
@Override public void removeTask(SubDownloadLoader fileer) {
@Override public void removeTask(SubDLoadUtil fileer) {
removeTaskFromExecQ(fileer);
mCache.remove(fileer.getKey());
}
@ -172,7 +171,7 @@ class SimpleSubQueue implements ISubQueue<SubDownloadLoader> {
ALog.d(TAG, "删除组合任务");
Set<String> keys = mExec.keySet();
for (String key : keys) {
SubDownloadLoader loader = mExec.get(key);
SubDLoadUtil loader = mExec.get(key);
if (loader != null) {
ALog.d(TAG, String.format("停止子任务:%s", loader.getEntity().getFileName()));
loader.cancel();
@ -180,7 +179,7 @@ class SimpleSubQueue implements ISubQueue<SubDownloadLoader> {
}
}
@Override public SubDownloadLoader getNextTask() {
@Override public SubDLoadUtil getNextTask() {
Iterator<String> keys = mCache.keySet().iterator();
if (keys.hasNext()) {
return mCache.get(keys.next());

@ -19,7 +19,6 @@ import android.os.Handler;
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.DGTaskWrapper;
import com.arialyy.aria.core.download.DTaskWrapper;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.downloader.Downloader;
@ -33,7 +32,7 @@ import com.arialyy.aria.util.ALog;
/**
* 子任务下载器负责创建{@link Downloader}
*/
class SubDownloadLoader implements IUtil {
class SubDLoadUtil implements IUtil {
private final String TAG = "SubDownloadLoader";
private Downloader mDownloader;
@ -46,11 +45,11 @@ class SubDownloadLoader implements IUtil {
* @param schedulers 调度器
* @param needGetInfo {@code true} 需要获取文件信息{@code false} 不需要获取文件信息
*/
SubDownloadLoader(Handler schedulers, DTaskWrapper taskWrapper, boolean needGetInfo) {
SubDLoadUtil(Handler schedulers, DTaskWrapper taskWrapper, boolean needGetInfo) {
mWrapper = taskWrapper;
mSchedulers = schedulers;
this.needGetInfo = needGetInfo;
mListener = new ChildDownloadListener(mSchedulers, SubDownloadLoader.this);
mListener = new ChildDownloadListener(mSchedulers, SubDLoadUtil.this);
}
@Override public String getKey() {
@ -113,7 +112,7 @@ class SubDownloadLoader implements IUtil {
}
@Override public void onFail(AbsEntity entity, BaseException e, boolean needRetry) {
mSchedulers.obtainMessage(ISchedulers.FAIL, SubDownloadLoader.this);
mSchedulers.obtainMessage(ISchedulers.FAIL, SubDLoadUtil.this);
}
})).start();
} else {

@ -20,7 +20,6 @@ import android.os.Looper;
import android.support.annotation.CheckResult;
import android.text.TextUtils;
import com.arialyy.aria.core.command.CancelCmd;
import com.arialyy.aria.core.command.ICmd;
import com.arialyy.aria.core.command.NormalCmdFactory;
import com.arialyy.aria.core.download.DGTaskWrapper;
import com.arialyy.aria.core.download.DTaskWrapper;
@ -193,11 +192,11 @@ public abstract class AbsTarget<TARGET extends AbsTarget> implements ITargetHand
protected int checkTaskType() {
int taskType = 0;
if (mTaskWrapper instanceof DTaskWrapper) {
taskType = ICmd.TASK_TYPE_DOWNLOAD;
taskType = ITask.DOWNLOAD;
} else if (mTaskWrapper instanceof DGTaskWrapper) {
taskType = ICmd.TASK_TYPE_DOWNLOAD_GROUP;
taskType = ITask.DOWNLOAD_GROUP;
} else if (mTaskWrapper instanceof UTaskWrapper) {
taskType = ICmd.TASK_TYPE_UPLOAD;
taskType = ITask.UPLOAD;
}
return taskType;
}
@ -209,8 +208,9 @@ public abstract class AbsTarget<TARGET extends AbsTarget> implements ITargetHand
boolean b = checkEntity();
ISchedulers schedulers = getScheduler();
if (!b && schedulers != null) {
new Handler(Looper.getMainLooper(), schedulers).obtainMessage(ISchedulers.FAIL,
new TempTask(mTaskWrapper, mEntity)).sendToTarget();
new Handler(Looper.getMainLooper(), schedulers).obtainMessage(ISchedulers.CHECK_FAIL,
checkTaskType(), -1, null).sendToTarget();
}
return b;
@ -365,83 +365,4 @@ public abstract class AbsTarget<TARGET extends AbsTarget> implements ITargetHand
checkTaskType()));
}
}
private static class TempTask implements ITask {
private AbsTaskWrapper wrapper;
private AbsEntity entity;
private TempTask(AbsTaskWrapper wrapper, AbsEntity entity) {
this.wrapper = wrapper;
this.entity = entity;
}
@Override public int getTaskType() {
return TEMP;
}
@Override public int getState() {
return entity.getState();
}
@Override public String getKey() {
return entity.getKey();
}
@Override public boolean isRunning() {
return false;
}
@Override public AbsTaskWrapper getTaskWrapper() {
return wrapper;
}
@Override public void start() {
}
@Override public void start(int type) {
}
@Override public void stop() {
}
@Override public void stop(int type) {
}
@Override public void cancel() {
}
@Override public void cancel(int type) {
}
@Override public Object getExpand(String key) {
return null;
}
@Override public boolean isStop() {
return false;
}
@Override public boolean isCancel() {
return false;
}
@Override public boolean isNeedRetry() {
return false;
}
@Override public String getTaskName() {
return "TempTask";
}
@Override public int getSchedulerType() {
return TaskSchedulerType.TYPE_DEFAULT;
}
}
}

@ -114,8 +114,8 @@ public class ThreadTaskManager {
container.threadTask.destroy();
}
temp.clear();
}
mThreadTasks.remove(key);
}
} catch (Exception e) {
e.printStackTrace();
} finally {

@ -148,11 +148,11 @@ abstract class AbsSchedulers<TASK_ENTITY extends AbsTaskWrapper, TASK extends IT
}
TASK task = (TASK) msg.obj;
if (task == null) {
if (task == null && msg.what != ISchedulers.CHECK_FAIL) {
ALog.e(TAG, "请传入下载任务");
return true;
}
handleNormalEvent(task, msg.what);
handleNormalEvent(task, msg.what, msg.arg1);
return true;
}
@ -260,7 +260,7 @@ abstract class AbsSchedulers<TASK_ENTITY extends AbsTaskWrapper, TASK extends IT
/**
* 处理普通任务和任务组的事件
*/
private void handleNormalEvent(TASK task, int what) {
private void handleNormalEvent(TASK task, int what, int arg1) {
switch (what) {
case STOP:
if (task.getState() == IEntity.STATE_WAIT) {
@ -269,7 +269,7 @@ abstract class AbsSchedulers<TASK_ENTITY extends AbsTaskWrapper, TASK extends IT
mQueue.removeTaskFormQueue(task.getKey());
if (mQueue.getCurrentExePoolNum() < mQueue.getMaxTaskNum()) {
ALog.d(TAG, String.format("停止任务【%s】成功,尝试开始下一任务", task.getTaskName()));
startNextTask(task);
startNextTask(task.getSchedulerType());
} else {
ALog.d(TAG, String.format("停止任务【%s】成功", task.getTaskName()));
}
@ -278,7 +278,7 @@ abstract class AbsSchedulers<TASK_ENTITY extends AbsTaskWrapper, TASK extends IT
mQueue.removeTaskFormQueue(task.getKey());
if (mQueue.getCurrentExePoolNum() < mQueue.getMaxTaskNum()) {
ALog.d(TAG, String.format("删除任务【%s】成功,尝试开始下一任务", task.getTaskName()));
startNextTask(task);
startNextTask(task.getSchedulerType());
} else {
ALog.d(TAG, String.format("删除任务【%s】成功", task.getTaskName()));
}
@ -286,12 +286,20 @@ abstract class AbsSchedulers<TASK_ENTITY extends AbsTaskWrapper, TASK extends IT
case COMPLETE:
mQueue.removeTaskFormQueue(task.getKey());
ALog.d(TAG, String.format("任务【%s】处理完成", task.getTaskName()));
startNextTask(task);
startNextTask(task.getSchedulerType());
break;
case FAIL:
handleFailTask(task);
break;
case CHECK_FAIL:
handlePreFailTask(arg1);
break;
}
if (what == FAIL || what == CHECK_FAIL) {
return;
}
if (what == CANCEL || what == COMPLETE) {
TaskWrapperManager.getInstance().removeTaskWrapper(task.getKey());
} else {
@ -299,9 +307,45 @@ abstract class AbsSchedulers<TASK_ENTITY extends AbsTaskWrapper, TASK extends IT
TaskWrapperManager.getInstance().putTaskWrapper(task.getKey(), task.getTaskWrapper());
}
}
if (what != FAIL) {
normalTaskCallback(what, task);
}
private void handlePreFailTask(int taskType) {
startNextTask(TaskSchedulerType.TYPE_DEFAULT);
// 发送广播
boolean canSend = manager.getAppConfig().isUseBroadcast();
if (canSend) {
Intent intent = new Intent(ISchedulers.ARIA_TASK_INFO_ACTION);
Bundle b = new Bundle();
b.putInt(ISchedulers.TASK_TYPE, taskType);
b.putInt(ISchedulers.TASK_STATE, ISchedulers.FAIL);
AriaManager.APP.sendBroadcast(intent);
}
// 处理回调
if (mObservers.size() > 0) {
Set<String> keys = mObservers.keySet();
for (String key : keys) {
Map<TaskEnum, ISchedulerListener> listeners = mObservers.get(key);
if (listeners == null || listeners.isEmpty()) {
continue;
}
NormalTaskListener<TASK> listener = null;
if (mObservers.get(key) != null) {
if (taskType == ITask.DOWNLOAD) {
listener = (NormalTaskListener<TASK>) listeners.get(TaskEnum.DOWNLOAD);
} else if (taskType == ITask.DOWNLOAD_GROUP) {
listener = (NormalTaskListener<TASK>) listeners.get(TaskEnum.DOWNLOAD_GROUP);
} else if (taskType == ITask.DOWNLOAD_GROUP) {
listener = (NormalTaskListener<TASK>) listeners.get(TaskEnum.UPLOAD);
}
}
if (listener != null) {
normalTaskCallback(ISchedulers.CHECK_FAIL, null, listener);
}
}
}
}
/**
@ -337,7 +381,7 @@ abstract class AbsSchedulers<TASK_ENTITY extends AbsTaskWrapper, TASK extends IT
private void normalTaskCallback(int state, TASK task, NormalTaskListener<TASK> listener) {
if (listener != null) {
if (task == null) {
if (task == null && state != ISchedulers.CHECK_FAIL) {
ALog.e(TAG, "TASK 为null,回调失败");
return;
}
@ -373,6 +417,9 @@ abstract class AbsSchedulers<TASK_ENTITY extends AbsTaskWrapper, TASK extends IT
listener.onTaskFail(task.getTaskType() == ITask.TEMP ? null : task,
(Exception) task.getExpand(AbsTask.ERROR_INFO_KEY));
break;
case CHECK_FAIL:
listener.onTaskFail(null, null);
break;
case NO_SUPPORT_BREAK_POINT:
listener.onNoSupportBreakPoint(task);
break;
@ -427,7 +474,7 @@ abstract class AbsSchedulers<TASK_ENTITY extends AbsTaskWrapper, TASK extends IT
private void handleFailTask(final TASK task) {
if (!task.isNeedRetry() || task.isStop() || task.isCancel()) {
mQueue.removeTaskFormQueue(task.getKey());
startNextTask(task);
startNextTask(task.getSchedulerType());
normalTaskCallback(FAIL, task);
return;
}
@ -439,7 +486,7 @@ abstract class AbsSchedulers<TASK_ENTITY extends AbsTaskWrapper, TASK extends IT
if ((!NetUtils.isConnected(AriaManager.APP) && !isNotNetRetry)
|| task.getTaskWrapper().getEntity().getFailNum() > reTryNum) {
mQueue.removeTaskFormQueue(task.getKey());
startNextTask(task);
startNextTask(task.getSchedulerType());
TaskWrapperManager.getInstance().removeTaskWrapper(task.getKey());
normalTaskCallback(FAIL, task);
return;
@ -456,7 +503,7 @@ abstract class AbsSchedulers<TASK_ENTITY extends AbsTaskWrapper, TASK extends IT
mQueue.reTryStart(task);
} else {
mQueue.removeTaskFormQueue(task.getKey());
startNextTask(task);
startNextTask(task.getSchedulerType());
TaskWrapperManager.getInstance().removeTaskWrapper(task.getKey());
}
}
@ -466,8 +513,8 @@ abstract class AbsSchedulers<TASK_ENTITY extends AbsTaskWrapper, TASK extends IT
/**
* 启动下一个任务条件任务停止取消下载任务完成
*/
private void startNextTask(TASK oldTask) {
if (oldTask.getSchedulerType() == TaskSchedulerType.TYPE_STOP_NOT_NEXT) {
private void startNextTask(int schedulerType) {
if (schedulerType == TaskSchedulerType.TYPE_STOP_NOT_NEXT) {
return;
}
TASK newTask = mQueue.getNextTask();

@ -130,6 +130,10 @@ public interface ISchedulers extends Handler.Callback {
* 等待
*/
int WAIT = 10;
/**
* 检查信息失败
*/
int CHECK_FAIL = 11;
/**
* 组合任务子任务预处理

@ -21,11 +21,11 @@ import android.text.TextUtils;
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.NormalCmdFactory;
import com.arialyy.aria.core.common.ProxyHelper;
import com.arialyy.aria.core.event.EventMsgUtil;
import com.arialyy.aria.core.inf.AbsReceiver;
import com.arialyy.aria.core.inf.ITask;
import com.arialyy.aria.core.inf.ReceiverType;
import com.arialyy.aria.core.scheduler.UploadSchedulers;
import com.arialyy.aria.orm.DbEntity;
@ -168,7 +168,7 @@ public class UploadReceiver extends AbsReceiver {
public void stopAllTask() {
EventMsgUtil.getDefault().post(NormalCmdFactory.getInstance()
.createCmd(new UTaskWrapper(null), NormalCmdFactory.TASK_STOP_ALL,
ICmd.TASK_TYPE_UPLOAD));
ITask.UPLOAD));
}
/**
@ -181,7 +181,7 @@ public class UploadReceiver extends AbsReceiver {
final AriaManager am = AriaManager.getInstance(AriaManager.APP);
CancelAllCmd cancelCmd =
(CancelAllCmd) CommonUtil.createNormalCmd(new UTaskWrapper(null),
NormalCmdFactory.TASK_CANCEL_ALL, ICmd.TASK_TYPE_UPLOAD);
NormalCmdFactory.TASK_CANCEL_ALL, ITask.UPLOAD);
cancelCmd.removeFile = removeFile;
EventMsgUtil.getDefault().post(cancelCmd);

@ -290,8 +290,11 @@ public class RecordUtil {
private static void removeTsCache(String cacheDir) {
if (!TextUtils.isEmpty(cacheDir)) {
File[] files = new File(cacheDir).listFiles();
File cacheDirF = new File(cacheDir);
if (!cacheDirF.exists()){
return;
}
File[] files = cacheDirF.listFiles();
for (File f : files) {
if (f.exists()) {
f.delete();

@ -1,6 +1,8 @@
## 开发日志
+ v_3.6.5
- fix bug https://github.com/AriaLyy/Aria/issues/403
- fix bug https://github.com/AriaLyy/Aria/issues/414
- fix bug https://github.com/AriaLyy/Aria/issues/406
- 新增ftp上传拦截器 https://github.com/AriaLyy/Aria/issues/402
- 重构线程任务模块
- 修复一个低版本数据库升级的问题 https://github.com/AriaLyy/Aria/issues/407

@ -72,6 +72,7 @@ dependencies {
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5.4'
implementation 'com.github.bumptech.glide:glide:3.7.0'
implementation 'com.pddstudio:highlightjs-android:1.5.0'
implementation 'org.greenrobot:eventbus:3.1.1'
}
repositories {
mavenCentral()

@ -0,0 +1,46 @@
/*
* 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.simple.common;
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import com.arialyy.frame.util.DensityUtils;
import com.arialyy.simple.R;
import com.arialyy.simple.base.BaseDialog;
import com.arialyy.simple.databinding.DialogLoadingBinding;
@SuppressLint("ValidFragment") public class LoadingDialog extends BaseDialog<DialogLoadingBinding> {
public LoadingDialog(Object obj) {
super(obj);
}
@Override protected int setLayoutId() {
return R.layout.dialog_loading;
}
@Override
public void onStart() {
super.onStart();
Dialog dialog = getDialog();
if (dialog != null) {
dialog.getWindow().setLayout(DensityUtils.dp2px(120), DensityUtils.dp2px(120));
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
getDialog().setCanceledOnTouchOutside(false);
}
}
}

@ -29,9 +29,7 @@ import android.view.MenuItem;
import android.view.MotionEvent;
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,7 +45,6 @@ import com.arialyy.simple.base.BaseActivity;
import com.arialyy.simple.common.ModifyPathDialog;
import com.arialyy.simple.common.ModifyUrlDialog;
import com.arialyy.simple.databinding.ActivitySingleBinding;
import com.arialyy.simple.util.AppUtil;
import java.io.File;
import java.io.IOException;
@ -243,9 +240,9 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
@Download.onTaskFail
void taskFail(DownloadTask task, Exception e) {
if (task.getKey().equals(mUrl)) {
Toast.makeText(SingleTaskActivity.this, getString(R.string.download_fail), Toast.LENGTH_SHORT)
.show();
if (task != null && task.getKey().equals(mUrl)) {
getBinding().setStateStr(getString(R.string.start));
}
}

@ -75,7 +75,7 @@ import java.util.List;
findViewById(R.id.stop).setOnClickListener(this);
findViewById(R.id.start).setOnClickListener(this);
findViewById(R.id.cancel).setOnClickListener(this);
//findViewById(R.id.cancel).setOnClickListener(this);
mGroup.setText("任务组:" + mGroupHash);
mSub.setText("子任务:" + mChildName);
mPb.setProgress((int) (mChildEntity.getCurrentProgress() * 100 / mChildEntity.getFileSize()));

@ -23,6 +23,7 @@ import com.arialyy.annotations.DownloadGroup;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadGroupEntity;
import com.arialyy.aria.core.download.DownloadGroupTarget;
import com.arialyy.aria.core.download.DownloadGroupTask;
import com.arialyy.aria.core.inf.IHttpFileLenAdapter;
import com.arialyy.aria.util.ALog;
@ -40,18 +41,23 @@ import java.util.Map;
*/
public class DownloadGroupActivity extends BaseActivity<ActivityDownloadGroupBinding> {
SubStateLinearLayout mChildList;
List<String> mUrls;
private SubStateLinearLayout mChildList;
private List<String> mUrls;
private DownloadGroupTarget mTarget;
@Override protected void init(Bundle savedInstanceState) {
super.init(savedInstanceState);
Aria.download(this).register();
setTitle("任务组");
mChildList = getBinding().childList;
mUrls = getModule(GroupModule.class).getUrls();
DownloadGroupEntity entity = Aria.download(this).getDownloadGroupEntity(mUrls);
if (entity != null) {
mTarget = Aria.download(this).loadGroup(entity);
mChildList.addData(entity.getSubEntities());
getBinding().setStateStr(
mTarget.isRunning() ? getString(R.string.stop) : getString(R.string.resume));
getBinding().setFileSize(entity.getConvertFileSize());
if (entity.getFileSize() == 0) {
getBinding().setProgress(0);
@ -59,7 +65,8 @@ public class DownloadGroupActivity extends BaseActivity<ActivityDownloadGroupBin
getBinding().setProgress(entity.isComplete() ? 100
: (int) (entity.getCurrentProgress() * 100 / entity.getFileSize()));
}
ALog.d(TAG, "size = " + entity.getSubEntities().size() + "; len = " + entity.getConvertFileSize());
ALog.d(TAG,
"size = " + entity.getSubEntities().size() + "; len = " + entity.getConvertFileSize());
}
mChildList.setOnItemClickListener(new SubStateLinearLayout.OnItemClickListener() {
@ -82,6 +89,7 @@ public class DownloadGroupActivity extends BaseActivity<ActivityDownloadGroupBin
public void onClick(View view) {
switch (view.getId()) {
case R.id.start:
if (mTarget == null || !mTarget.isRunning()) {
Aria.download(this)
.loadGroup(mUrls)
.setDirPath(
@ -106,9 +114,11 @@ public class DownloadGroupActivity extends BaseActivity<ActivityDownloadGroupBin
//.setFileSize(114981416)
//.updateUrls(temp)
.start();
break;
case R.id.stop:
getBinding().setStateStr(getString(R.string.stop));
} else {
Aria.download(this).loadGroup(mUrls).stop();
getBinding().setStateStr(getString(R.string.resume));
}
break;
case R.id.cancel:
Aria.download(this).loadGroup(mUrls).cancel(true);
@ -166,10 +176,12 @@ public class DownloadGroupActivity extends BaseActivity<ActivityDownloadGroupBin
L.d(TAG, "group task cancel");
getBinding().setSpeed("");
getBinding().setProgress(0);
getBinding().setStateStr(getString(R.string.start));
}
@DownloadGroup.onTaskFail() void taskFail(DownloadGroupTask task) {
L.d(TAG, "group task fail");
getBinding().setStateStr(getString(R.string.resume));
}
@DownloadGroup.onTaskComplete() void taskComplete(DownloadGroupTask task) {
@ -178,6 +190,7 @@ public class DownloadGroupActivity extends BaseActivity<ActivityDownloadGroupBin
mChildList.updateChildProgress(task.getEntity().getSubEntities());
T.showShort(this, "任务组下载完成");
L.d(TAG, "任务组下载完成");
getBinding().setStateStr(getString(R.string.start));
}
@DownloadGroup.onSubTaskRunning void onSubTaskRunning(DownloadGroupTask groupTask,

@ -45,9 +45,13 @@ import com.arialyy.simple.base.BaseActivity;
import com.arialyy.simple.common.ModifyPathDialog;
import com.arialyy.simple.common.ModifyUrlDialog;
import com.arialyy.simple.databinding.ActivityM3u8VodBinding;
import com.arialyy.simple.to.PeerIndex;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
public class M3U8VodDLoadActivity extends BaseActivity<ActivityM3u8VodBinding> {
@ -105,6 +109,21 @@ public class M3U8VodDLoadActivity extends BaseActivity<ActivityM3u8VodBinding> {
dialog.show(getSupportFragmentManager(), "ModifyPathDialog");
}
@Override protected void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override protected void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void jumpIndex(PeerIndex index) {
Aria.download(this).load(mUrl).asM3U8().asVod().jumPeerIndex(index.index);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_single_task_activity, menu);
@ -303,8 +322,6 @@ public class M3U8VodDLoadActivity extends BaseActivity<ActivityM3u8VodBinding> {
mModule.uploadUrl(this, String.valueOf(data));
} else if (result == ModifyPathDialog.MODIFY_PATH_RESULT) {
mModule.updateFilePath(this, String.valueOf(data));
} else if (result == VideoPlayerFragment.SEEK_BAR_PROGRESS_KEY) {
Aria.download(this).load(mUrl).asM3U8().asVod().jumPeerIndex((Integer) data);
}
}
}

@ -14,24 +14,29 @@ import android.view.View;
import android.widget.SeekBar;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.m3u8.M3U8Entity;
import com.arialyy.aria.util.ALog;
import com.arialyy.frame.base.BaseFragment;
import com.arialyy.simple.R;
import com.arialyy.simple.common.LoadingDialog;
import com.arialyy.simple.databinding.FragmentVideoPlayerBinding;
import com.arialyy.simple.to.PeerIndex;
import java.io.IOException;
import java.util.List;
import org.greenrobot.eventbus.EventBus;
@SuppressLint("ValidFragment")
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
public class VideoPlayerFragment extends BaseFragment<FragmentVideoPlayerBinding> {
static final int SEEK_BAR_PROGRESS_KEY = 0xC1;
private M3U8VodModule mModule;
private DownloadEntity mEntity;
private int mPeerIndex;
SparseArray<String> mPlayers = new SparseArray<>();
private SparseArray<String> mPlayers = new SparseArray<>();
private SurfaceHolder mSurfaceHolder;
private NextMediaPlayer nexPlayer;
private NextMediaPlayer mNextPlayer;
private MediaPlayer mCurrentPlayer;
private LoadingDialog mLoadingDialog;
private int mJumpIndex = -1;
VideoPlayerFragment(int peerIndex, DownloadEntity entity) {
mEntity = entity;
@ -46,13 +51,11 @@ public class VideoPlayerFragment extends BaseFragment<FragmentVideoPlayerBinding
@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());
startNewPlayer(mPlayers.valueAt(0));
}
@Override
@ -61,7 +64,12 @@ public class VideoPlayerFragment extends BaseFragment<FragmentVideoPlayerBinding
}
@Override public void surfaceDestroyed(SurfaceHolder holder) {
if (mCurrentPlayer != null) {
mCurrentPlayer.release();
}
if (mNextPlayer != null) {
mNextPlayer.getPlayer().release();
}
}
});
getBinding().seekBar.setMax(mEntity.getM3U8Entity().getPeerNum());
@ -75,36 +83,66 @@ public class VideoPlayerFragment extends BaseFragment<FragmentVideoPlayerBinding
}
@Override public void onStopTrackingTouch(SeekBar seekBar) {
dataCallback(SEEK_BAR_PROGRESS_KEY, seekBar.getProgress());
PeerIndex index = new PeerIndex();
index.index = seekBar.getProgress();
EventBus.getDefault().post(index);
if (mCurrentPlayer != null && mCurrentPlayer.isPlaying()) {
mCurrentPlayer.stop();
mCurrentPlayer.setDisplay(null);
mCurrentPlayer.release();
}
showLoadingDialog();
mJumpIndex = 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();
if (mCurrentPlayer != null) {
if (mCurrentPlayer.isPlaying()) {
getBinding().controlBt.setSelected(true);
mCurrentPlayer.start();
} else {
getBinding().controlBt.setSelected(false);
mCurrentPlayer.stop();
}
}
}
});
}
firstPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
private void startNewPlayer(String source) {
if (TextUtils.isEmpty(source)) {
ALog.e(TAG, "资源路径为空");
return;
}
try {
mCurrentPlayer = new MediaPlayer();
mCurrentPlayer.setScreenOnWhilePlaying(true);
mCurrentPlayer.setSurface(mSurfaceHolder.getSurface());
mCurrentPlayer.setDataSource(source);
mCurrentPlayer.prepareAsync();
mCurrentPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override public void onPrepared(MediaPlayer mp) {
mp.start();
setNextMediaPlayer(mp);
}
});
firstPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
mCurrentPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override public void onCompletion(MediaPlayer mp) {
mp.setDisplay(null);
nexPlayer.getPlayer().setSurface(mSurfaceHolder.getSurface());
nexPlayer.start();
mNextPlayer.getPlayer().setSurface(mSurfaceHolder.getSurface());
mNextPlayer.start();
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 设置下一个分片
*/
@ -112,33 +150,53 @@ public class VideoPlayerFragment extends BaseFragment<FragmentVideoPlayerBinding
mPeerIndex++;
String nextPeerPath = mPlayers.get(mPeerIndex);
if (!TextUtils.isEmpty(nextPeerPath)) {
nexPlayer = new NextMediaPlayer(nextPeerPath);
nexPlayer.prepareAsync();
mNextPlayer = new NextMediaPlayer(nextPeerPath);
mNextPlayer.prepareAsync();
nexPlayer.setListener(new NextMediaPlayer.StateListener() {
mNextPlayer.setListener(new NextMediaPlayer.StateListener() {
@Override public void onStart(MediaPlayer mp) {
mCurrentPlayer = mp;
setNextMediaPlayer(mp);
}
@Override public void onCompletion(MediaPlayer mp) {
mp.setDisplay(null);
nexPlayer.getPlayer().setSurface(mSurfaceHolder.getSurface());
nexPlayer.start();
//mp.setDisplay(null);
//mNextPlayer.getPlayer().setSurface(mSurfaceHolder.getSurface());
mNextPlayer.start();
}
@Override public void onPrepared(MediaPlayer mp) {
lastPlayer.setNextMediaPlayer(nexPlayer.getPlayer());
lastPlayer.setNextMediaPlayer(mNextPlayer.getPlayer());
}
});
}
}
private void showLoadingDialog() {
if (mLoadingDialog == null) {
mLoadingDialog = new LoadingDialog(this);
}
if (!mLoadingDialog.isHidden()) {
mLoadingDialog.show(getChildFragmentManager(), "mLoadingDialog");
}
}
private void dismissDialog() {
if (mLoadingDialog != null) {
mLoadingDialog.dismiss();
}
}
@Override protected int setLayoutId() {
return R.layout.fragment_video_player;
}
public void addPlayer(int peerIndex, String peerPath) {
mPlayers.put(peerIndex, peerPath);
if (mJumpIndex != -1 && mJumpIndex == peerIndex) {
startNewPlayer(mPlayers.get(peerIndex));
dismissDialog();
}
}
private static class NextMediaPlayer implements MediaPlayer.OnPreparedListener,

@ -0,0 +1,20 @@
/*
* 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.simple.to;
public class PeerIndex {
public int index;
}

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#99000000"/>
<corners android:radius="8dp"/>
</shape>

@ -15,6 +15,11 @@
name="progress"
type="int"
/>
<variable
name="stateStr"
type="String"
/>
</data>
<RelativeLayout
@ -26,7 +31,7 @@
<include layout="@layout/layout_bar"/>
<include
layout="@layout/content_single"
layout="@layout/layout_content_single"
android:id="@+id/content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -34,6 +39,7 @@
bind:fileSize="@{fileSize}"
bind:progress="@{progress}"
bind:speed="@{speed}"
bind:stateStr="@{stateStr}"
/>
<com.arialyy.simple.widget.SubStateLinearLayout

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<RelativeLayout
android:layout_width="120dp"
android:layout_height="120dp"
android:background="@drawable/bg_loading"
android:orientation="vertical"
>
<ProgressBar
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_centerInParent="true"
/>
</RelativeLayout>
</layout>

@ -12,7 +12,7 @@
<SurfaceView
android:id="@+id/surface_view"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_height="240dp"
/>
@ -31,7 +31,8 @@
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:clickable="true"
app:srcCompat="@drawable/ic_start"
android:visibility="visible"
app:srcCompat="@drawable/selector_start_stop_bt"
/>
<SeekBar

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 MiB

Loading…
Cancel
Save