最高优先级任务功能实现,demo修改

This commit is contained in:
AriaLyy
2017-06-03 15:55:09 +08:00
parent 52a4f1e7ea
commit 1764f50258
40 changed files with 435 additions and 410 deletions

View File

@ -177,9 +177,9 @@ import com.arialyy.aria.core.upload.UploadTask;
/**
* 预处理有时有些地址链接比较慢这时可以先在这个地方出来一些界面上的UI如按钮的状态。
*
* @param url 任务上传地址
* @param task 上传文物实体
*/
@Override public void onPre(String url) {
@Override public void onPre(UploadTask task) {
}
@ -223,10 +223,11 @@ import com.arialyy.aria.core.upload.UploadTask;
implements IDownloadSchedulerListener<DownloadTask> {
/**
* 预处理有时有些地址链接比较慢这时可以先在这个地方出来一些界面上的UI如按钮的状态。
* 需要注意的是在该回调中是得不到文件长度的如果需要获取文件长度需要在onTaskPre中获取
*
* @param url 任务下载地址
* @param task 下载任务
*/
@Override public void onPre(String url) {
@Override public void onPre(DownloadTask task) {
}

View File

@ -47,7 +47,7 @@ final class HighestPriorityCmd<T extends ITaskEntity> extends AbsCmd<T> {
if (!TextUtils.isEmpty(mTargetName)) {
task.setTargetName(mTargetName);
}
task.setHighestPriority(true);
mQueue.setTaskHighestPriority(task);
}
}
}

View File

@ -76,7 +76,7 @@ public class DownloadTask implements ITask {
}
/**
* @return 返回转换单位后的速度需要你在配置文件中配置转换完成后为1b/s、1k/s、1m/s、1g/s、1t/s
* @return 返回转换单位后的速度需要你在配置文件中配置转换完成后为1b/s、1kb/s、1mb/s、1gb/s、1tb/s
* <pre>
* {@code
* <xml>
@ -118,11 +118,11 @@ public class DownloadTask implements ITask {
/**
* 转换单位后的文件长度
*
* @return 如果文件长度为0则返回0m否则返回转换后的长度1b、1k、1m、1g、1t
* @return 如果文件长度为0则返回0m否则返回转换后的长度1b、1kb、1mb、1gb、1tb
*/
@Override public String getConvertFileSize() {
if (mEntity.getFileSize() == 0) {
return "0m";
return "0mb";
}
return CommonUtil.formatFileSize(mEntity.getFileSize());
}
@ -134,6 +134,18 @@ public class DownloadTask implements ITask {
return mEntity.getCurrentProgress();
}
/**
* 获取单位转换后的进度
*
* @return 如已经下载3mb的大小则返回{@code 3mb}
*/
@Override public String getConvertCurrentProgress() {
if (mEntity.getCurrentProgress() == 0) {
return "0b";
}
return CommonUtil.formatFileSize(mEntity.getCurrentProgress());
}
/**
* 获取当前下载任务的下载地址
*

View File

@ -35,11 +35,20 @@ import java.util.Set;
/**
* Created by lyy on 2017/2/28.
*/
public class AbsTarget<ENTITY extends IEntity, TASK_ENTITY extends ITaskEntity> {
public abstract class AbsTarget<ENTITY extends IEntity, TASK_ENTITY extends ITaskEntity> {
protected ENTITY entity;
protected TASK_ENTITY taskEntity;
protected String targetName;
/**
* 获取任务状态
*
* @return {@link IEntity}
*/
public int getTaskState() {
return entity.getState();
}
/**
* 将任务设置为最高优先级任务,最高优先级任务有以下特点:
* 1、在下载队列中有且只有一个最高优先级任务

View File

@ -0,0 +1,9 @@
package com.arialyy.aria.core.inf;
/**
* Created by lyy on 2017/6/3.
*/
public abstract class AbsTask implements ITask{
}

View File

@ -81,8 +81,17 @@ public interface ITask {
*/
public String getConvertFileSize();
/**
* 获取当前进度
*/
public long getCurrentProgress();
/**
* 获取单位转换后的进度
* @return 返回 3mb
*/
public String getConvertCurrentProgress();
public void setTargetName(String targetName);
public void removeRecord();

View File

@ -87,6 +87,7 @@ abstract class AbsTaskQueue<TASK extends ITask, TASK_ENTITY extends ITaskEntity,
@Override public void stopTask(TASK task) {
if (!task.isRunning()) Log.w(TAG, "停止任务失败,【任务已经停止】");
task.setHighestPriority(false);
if (mExecutePool.removeTask(task)) {
task.stop();
} else {

View File

@ -26,6 +26,7 @@ import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.queue.pool.ExecutePool;
import com.arialyy.aria.core.scheduler.DownloadSchedulers;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
/**
@ -52,6 +53,20 @@ public class DownloadTaskQueue
}
@Override public void setTaskHighestPriority(DownloadTask task) {
task.setHighestPriority(true);
Map<String, DownloadTask> exeTasks = mExecutePool.getAllTask();
if (exeTasks != null && !exeTasks.isEmpty()) {
Set<String> keys = exeTasks.keySet();
for (String key : keys) {
DownloadTask temp = exeTasks.get(key);
if (temp != null && temp.isRunning() && temp.isHighestPriorityTask() && !temp.getKey()
.equals(task.getKey())) {
Log.e(TAG, "设置最高优先级任务失败,失败原因【任务中已经有最高优先级任务,请等待上一个最高优先级任务完成,或手动暂停该任务】");
task.setHighestPriority(false);
return;
}
}
}
int maxSize = AriaManager.getInstance(AriaManager.APP).getDownloadConfig().getMaxTaskNum();
int currentSize = mExecutePool.size();
if (currentSize == 0 || currentSize < maxSize) {

View File

@ -34,12 +34,19 @@ public class CachePool<TASK extends ITask> implements IPool<TASK> {
private static final Object LOCK = new Object();
private static final int MAX_NUM = Integer.MAX_VALUE; //最大下载任务数
private static final long TIME_OUT = 1000;
private Map<String, TASK> mCacheArray;
private Map<String, TASK> mCacheMap;
private LinkedBlockingQueue<TASK> mCacheQueue;
public CachePool() {
mCacheQueue = new LinkedBlockingQueue<>(MAX_NUM);
mCacheArray = new HashMap<>();
mCacheMap = new HashMap<>();
}
/**
* 获取所有正在执行的任务
*/
public Map<String, TASK> getAllTask() {
return mCacheMap;
}
@Override public boolean putTask(TASK task) {
@ -56,7 +63,7 @@ public class CachePool<TASK extends ITask> implements IPool<TASK> {
boolean s = mCacheQueue.offer(task);
Log.d(TAG, "任务添加" + (s ? "成功" : "失败,【" + url + ""));
if (s) {
mCacheArray.put(CommonUtil.keyToHashKey(url), task);
mCacheMap.put(CommonUtil.keyToHashKey(url), task);
}
return s;
}
@ -70,7 +77,7 @@ public class CachePool<TASK extends ITask> implements IPool<TASK> {
task = mCacheQueue.poll(TIME_OUT, TimeUnit.MICROSECONDS);
if (task != null) {
String url = task.getKey();
mCacheArray.remove(CommonUtil.keyToHashKey(url));
mCacheMap.remove(CommonUtil.keyToHashKey(url));
}
return task;
} catch (InterruptedException e) {
@ -87,7 +94,7 @@ public class CachePool<TASK extends ITask> implements IPool<TASK> {
return null;
}
String key = CommonUtil.keyToHashKey(downloadUrl);
return mCacheArray.get(key);
return mCacheMap.get(key);
}
}
@ -98,7 +105,7 @@ public class CachePool<TASK extends ITask> implements IPool<TASK> {
return false;
} else {
String key = CommonUtil.keyToHashKey(task.getKey());
mCacheArray.remove(key);
mCacheMap.remove(key);
return mCacheQueue.remove(task);
}
}
@ -111,8 +118,8 @@ public class CachePool<TASK extends ITask> implements IPool<TASK> {
return false;
}
String key = CommonUtil.keyToHashKey(downloadUrl);
TASK task = mCacheArray.get(key);
mCacheArray.remove(key);
TASK task = mCacheMap.get(key);
mCacheMap.remove(key);
return mCacheQueue.remove(task);
}
}

View File

@ -23,6 +23,7 @@ import com.arialyy.aria.core.inf.ITask;
import com.arialyy.aria.util.CommonUtil;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;
@ -35,7 +36,7 @@ public class ExecutePool<TASK extends ITask> implements IPool<TASK> {
private static final Object LOCK = new Object();
private static final long TIME_OUT = 1000;
private ArrayBlockingQueue<TASK> mExecuteQueue;
private Map<String, TASK> mExecuteArray;
private Map<String, TASK> mExecuteMap;
private int mSize;
public ExecutePool(boolean isDownload) {
@ -45,7 +46,14 @@ public class ExecutePool<TASK extends ITask> implements IPool<TASK> {
mSize = AriaManager.getInstance(AriaManager.APP).getUploadConfig().getMaxTaskNum();
}
mExecuteQueue = new ArrayBlockingQueue<>(mSize);
mExecuteArray = new HashMap<>();
mExecuteMap = new HashMap<>();
}
/**
* 获取所有正在执行的任务
*/
public Map<String, TASK> getAllTask() {
return mExecuteMap;
}
@Override public boolean putTask(TASK task) {
@ -60,6 +68,10 @@ public class ExecutePool<TASK extends ITask> implements IPool<TASK> {
return false;
} else {
if (mExecuteQueue.size() >= mSize) {
Set<String> keys = mExecuteMap.keySet();
for (String key : keys) {
if (mExecuteMap.get(key).isHighestPriorityTask()) return false;
}
if (pollFirstTask()) {
return putNewTask(task);
}
@ -100,7 +112,7 @@ public class ExecutePool<TASK extends ITask> implements IPool<TASK> {
boolean s = mExecuteQueue.offer(newTask);
Log.w(TAG, "任务添加" + (s ? "成功" : "失败,【" + url + ""));
if (s) {
mExecuteArray.put(CommonUtil.keyToHashKey(url), newTask);
mExecuteMap.put(CommonUtil.keyToHashKey(url), newTask);
}
return s;
}
@ -120,7 +132,7 @@ public class ExecutePool<TASK extends ITask> implements IPool<TASK> {
}
oldTask.stop();
String key = CommonUtil.keyToHashKey(oldTask.getKey());
mExecuteArray.remove(key);
mExecuteMap.remove(key);
} catch (InterruptedException e) {
e.printStackTrace();
return false;
@ -135,7 +147,7 @@ public class ExecutePool<TASK extends ITask> implements IPool<TASK> {
task = mExecuteQueue.poll(TIME_OUT, TimeUnit.MICROSECONDS);
if (task != null) {
String url = task.getKey();
mExecuteArray.remove(CommonUtil.keyToHashKey(url));
mExecuteMap.remove(CommonUtil.keyToHashKey(url));
}
return task;
} catch (InterruptedException e) {
@ -152,7 +164,7 @@ public class ExecutePool<TASK extends ITask> implements IPool<TASK> {
return null;
}
String key = CommonUtil.keyToHashKey(downloadUrl);
return mExecuteArray.get(key);
return mExecuteMap.get(key);
}
}
@ -163,7 +175,7 @@ public class ExecutePool<TASK extends ITask> implements IPool<TASK> {
return false;
} else {
String key = CommonUtil.keyToHashKey(task.getKey());
mExecuteArray.remove(key);
mExecuteMap.remove(key);
return mExecuteQueue.remove(task);
}
}
@ -176,8 +188,8 @@ public class ExecutePool<TASK extends ITask> implements IPool<TASK> {
return false;
}
String key = CommonUtil.keyToHashKey(downloadUrl);
TASK task = mExecuteArray.get(key);
mExecuteArray.remove(key);
TASK task = mExecuteMap.get(key);
mExecuteMap.remove(key);
return mExecuteQueue.remove(task);
}
}

View File

@ -129,7 +129,7 @@ public class DownloadSchedulers implements ISchedulers<DownloadTask> {
}
switch (state) {
case PRE:
listener.onPre(task.getKey());
listener.onPre(task);
break;
case POST_PRE:
listener.onTaskPre(task);

View File

@ -25,7 +25,7 @@ public interface ISchedulerListener<TASK extends ITask> {
* 预处理有时有些地址链接比较慢这时可以先在这个地方出来一些界面上的UI如按钮的状态。
* 在这个回调中,任务是获取不到文件大小,下载速度等参数
*/
public void onPre(String url);
public void onPre(TASK task);
/**
* 任务预加载完成

View File

@ -132,7 +132,7 @@ public class UploadSchedulers implements ISchedulers<UploadTask> {
}
switch (state) {
case PRE:
listener.onPre(task.getKey());
listener.onPre(task);
break;
case POST_PRE:
listener.onTaskPre(task);

View File

@ -139,7 +139,7 @@ public class UploadTask implements ITask {
}
/**
* @return 返回转换单位后的速度需要你在配置文件中配置转换完成后为1b/s、1k/s、1m/s、1g/s、1t/s
* @return 返回转换单位后的速度需要你在配置文件中配置转换完成后为1b/s、1kb/s、1mb/s、1gb/s、1tb/s
* <pre>
* {@code
* <xml>
@ -175,7 +175,7 @@ public class UploadTask implements ITask {
/**
* 转换单位后的文件长度
*
* @return 如果文件长度为0则返回0m否则返回转换后的长度1b、1k、1m、1g、1t
* @return 如果文件长度为0则返回0m否则返回转换后的长度1b、1kb、1mb、1gb、1tb
*/
@Override public String getConvertFileSize() {
if (mUploadEntity.getFileSize() == 0) {
@ -192,6 +192,18 @@ public class UploadTask implements ITask {
return mUploadEntity.getCurrentProgress();
}
/**
* 获取单位转换后的进度
*
* @return 如已经下载3mb的大小则返回{@code 3mb}
*/
@Override public String getConvertCurrentProgress() {
if (mUploadEntity.getCurrentProgress() == 0) {
return "0b";
}
return CommonUtil.formatFileSize(mUploadEntity.getCurrentProgress());
}
private static class UListener extends UploadListener {
WeakReference<Handler> outHandler;
WeakReference<UploadTask> task;

View File

@ -207,22 +207,22 @@ public class CommonUtil {
double megaByte = kiloByte / 1024;
if (megaByte < 1) {
BigDecimal result1 = new BigDecimal(Double.toString(kiloByte));
return result1.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "k";
return result1.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "kb";
}
double gigaByte = megaByte / 1024;
if (gigaByte < 1) {
BigDecimal result2 = new BigDecimal(Double.toString(megaByte));
return result2.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "m";
return result2.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "mb";
}
double teraBytes = gigaByte / 1024;
if (teraBytes < 1) {
BigDecimal result3 = new BigDecimal(Double.toString(gigaByte));
return result3.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "g";
return result3.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "gb";
}
BigDecimal result4 = new BigDecimal(teraBytes);
return result4.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "t";
return result4.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "tb";
}
/**

View File

@ -17,7 +17,6 @@ package com.arialyy.aria.util;
import android.text.TextUtils;
import android.util.Log;
import com.arialyy.aria.window.FileEntity;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
@ -27,8 +26,6 @@ import java.io.InputStream;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
/**
* Created by lyy on 2017/3/21.
@ -138,21 +135,4 @@ public class FileUtil {
}
}
}
/**
* 文件列表
*/
public List<FileEntity> loadFiles(String path) {
File file = new File(path);
File[] files = file.listFiles();
List<FileEntity> list = new ArrayList<>();
for (File f : files) {
FileEntity entity = new FileEntity();
entity.fileName = f.getName();
//entity.fileInfo = getFileType(f.getPath());
//entity.fileDrawable = getApkIcon(mContext, f.getPath());
list.add(entity);
}
return list;
}
}

View File

@ -1,67 +0,0 @@
/*
* 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.window;
import android.os.Bundle;
import android.os.Environment;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.widget.AbsListView;
import android.widget.ListView;
import com.arialyy.aria.R;
import com.arialyy.aria.util.FileUtil;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by lyy on 2017/3/21.
* 文件选择
*/
class AriaFileChangeActivity extends FragmentActivity {
final String ROOT_PAT = Environment.getExternalStorageDirectory().getPath();
ListView mList;
FileChangeAdapter mAdapter;
Map<String, List<FileEntity>> mData = new HashMap<>();
private String mCurrentPath = ROOT_PAT;
@Override protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_aria_file_shange);
mList = (ListView) findViewById(R.id.list);
mList.setOnScrollListener(new AbsListView.OnScrollListener() {
int state;
@Override public void onScrollStateChanged(AbsListView view, int scrollState) {
state = scrollState;
}
@Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
int totalItemCount) {
if (state == AbsListView.OnScrollListener.SCROLL_STATE_IDLE
&& firstVisibleItem + visibleItemCount == totalItemCount) {
loadMore();
}
}
});
}
private void loadMore() {
}
}

View File

@ -1,92 +0,0 @@
/*
* 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.window;
import android.content.Context;
import android.util.SparseBooleanArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;
import com.arialyy.aria.R;
import java.util.ArrayList;
import java.util.List;
/**
* Created by lyy on 2017/3/21.
*/
final class FileChangeAdapter extends BaseAdapter {
List<FileEntity> mData = new ArrayList<>();
SparseBooleanArray mCheck = new SparseBooleanArray();
Context mContext;
public FileChangeAdapter(Context context, List<FileEntity> list) {
mContext = context;
mData.addAll(list);
for (int i = 0, len = mData.size(); i < len; i++) {
mCheck.append(i, false);
}
}
@Override public int getCount() {
return mData.size();
}
@Override public Object getItem(int position) {
return null;
}
@Override public long getItemId(int position) {
return 0;
}
@Override public View getView(int position, View convertView, ViewGroup parent) {
FileChangeHolder holder = null;
if (convertView == null) {
convertView = LayoutInflater.from(mContext).inflate(R.layout.item_file, null);
holder = new FileChangeHolder(convertView);
convertView.setTag(holder);
} else {
holder = (FileChangeHolder) convertView.getTag();
}
holder.checkBox.setChecked(mCheck.get(position, false));
return convertView;
}
public void setCheck(int position, boolean check) {
if (position >= mData.size()) return;
mCheck.put(position, check);
notifyDataSetChanged();
}
private static class FileChangeHolder {
TextView title, info;
ImageView icon;
CheckBox checkBox;
FileChangeHolder(View view) {
title = (TextView) view.findViewById(R.id.title);
info = (TextView) view.findViewById(R.id.info);
icon = (ImageView) view.findViewById(R.id.icon);
checkBox = (CheckBox) view.findViewById(R.id.checkbox);
}
}
}

View File

@ -1,29 +0,0 @@
/*
* 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.window;
import android.graphics.drawable.Drawable;
/**
* Created by lyy on 2017/3/21.
*/
class FileEntity {
public String fileName;
public String fileInfo;
public int fileIcon;
public Drawable fileDrawable;
}