框架调整

pull/330/head
AriaLyy 8 years ago
parent 577b3d2546
commit efdfb62282
  1. 2
      .idea/misc.xml
  2. 4
      .idea/modules.xml
  3. 2
      Aria/src/main/java/com/arialyy/aria/core/Aria.java
  4. 15
      Aria/src/main/java/com/arialyy/aria/core/AriaManager.java
  5. 3
      Aria/src/main/java/com/arialyy/aria/core/command/AddCmd.java
  6. 2
      Aria/src/main/java/com/arialyy/aria/core/command/CancelCmd.java
  7. 3
      Aria/src/main/java/com/arialyy/aria/core/command/IDownloadCmd.java
  8. 2
      Aria/src/main/java/com/arialyy/aria/core/command/StartCmd.java
  9. 7
      Aria/src/main/java/com/arialyy/aria/core/command/StopCmd.java
  10. 3
      Aria/src/main/java/com/arialyy/aria/core/download/ConnectionHelp.java
  11. 39
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadEntity.java
  12. 2
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadListener.java
  13. 2
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java
  14. 2
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadStateConstance.java
  15. 71
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadTask.java
  16. 12
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadTaskFactory.java
  17. 9
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadUtil.java
  18. 2
      Aria/src/main/java/com/arialyy/aria/core/download/IDownloadListener.java
  19. 2
      Aria/src/main/java/com/arialyy/aria/core/download/IDownloadUtil.java
  20. 10
      Aria/src/main/java/com/arialyy/aria/core/download/SingleThreadTask.java
  21. 47
      Aria/src/main/java/com/arialyy/aria/core/inf/IEntity.java
  22. 28
      Aria/src/main/java/com/arialyy/aria/core/inf/ITask.java
  23. 3
      Aria/src/main/java/com/arialyy/aria/core/inf/ITaskEntity.java
  24. 17
      Aria/src/main/java/com/arialyy/aria/core/queue/AbsTaskQueue.java
  25. 52
      Aria/src/main/java/com/arialyy/aria/core/queue/DownloadTaskQueue.java
  26. 54
      Aria/src/main/java/com/arialyy/aria/core/queue/IDownloader.java
  27. 12
      Aria/src/main/java/com/arialyy/aria/core/queue/IPool.java
  28. 43
      Aria/src/main/java/com/arialyy/aria/core/queue/ITaskQueue.java
  29. 44
      Aria/src/main/java/com/arialyy/aria/core/queue/pool/CachePool.java
  30. 58
      Aria/src/main/java/com/arialyy/aria/core/queue/pool/ExecutePool.java
  31. 2
      Aria/src/main/java/com/arialyy/aria/core/scheduler/DownloadSchedulers.java
  32. 2
      Aria/src/main/java/com/arialyy/aria/core/scheduler/OnSchedulerListener.java
  33. 4
      Aria/src/main/java/com/arialyy/aria/core/upload/UploadEntity.java
  34. 39
      Aria/src/main/java/com/arialyy/aria/core/upload/UploadListener.java
  35. 114
      Aria/src/main/java/com/arialyy/aria/core/upload/UploadTask.java
  36. 49
      Aria/src/main/java/com/arialyy/aria/core/upload/UploadTaskQueue.java
  37. 331
      Aria/src/main/java/com/arialyy/aria/util/BufferedRandomAccessFile.java
  38. 4
      app/src/main/java/com/arialyy/simple/dialog_task/DownloadDialog.java
  39. 4
      app/src/main/java/com/arialyy/simple/fragment_task/DownloadFragment.java
  40. 2
      app/src/main/java/com/arialyy/simple/multi_task/DownloadActivity.java
  41. 4
      app/src/main/java/com/arialyy/simple/multi_task/DownloadAdapter.java
  42. 2
      app/src/main/java/com/arialyy/simple/multi_task/MultiTaskActivity.java
  43. 2
      app/src/main/java/com/arialyy/simple/notification/SimpleNotification.java
  44. 4
      app/src/main/java/com/arialyy/simple/pop_task/DownloadPopupWindow.java
  45. 2
      app/src/main/java/com/arialyy/simple/single_task/SingleTaskActivity.java

@ -37,7 +37,7 @@
<ConfirmationsSetting value="0" id="Add" />
<ConfirmationsSetting value="0" id="Remove" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">

@ -2,8 +2,8 @@
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/Aria.iml" filepath="$PROJECT_DIR$/Aria.iml" />
<module fileurl="file://$PROJECT_DIR$/Aria/Aria-Aria.iml" filepath="$PROJECT_DIR$/Aria/Aria-Aria.iml" />
<module fileurl="file://$PROJECT_DIR$/Aria/Aria.iml" filepath="$PROJECT_DIR$/Aria/Aria.iml" />
<module fileurl="file://$PROJECT_DIR$/AriaPrj.iml" filepath="$PROJECT_DIR$/AriaPrj.iml" />
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
</modules>
</component>

@ -28,7 +28,7 @@ import android.os.Build;
import android.widget.PopupWindow;
import com.arialyy.aria.core.download.DownloadReceiver;
import com.arialyy.aria.core.scheduler.OnSchedulerListener;
import com.arialyy.aria.core.task.DownloadTask;
import com.arialyy.aria.core.download.DownloadTask;
/**
* Created by lyy on 2016/12/1.

@ -20,6 +20,7 @@ import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Application;
import android.app.Dialog;
import android.app.Service;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
@ -57,16 +58,14 @@ import java.util.Map;
@SuppressLint("StaticFieldLeak") private static volatile AriaManager INSTANCE = null;
Map<String, IReceiver> mReceivers = new HashMap<>();
private LifeCallback mLifeCallback;
DownloadTaskQueue mDTaskQueue;
public static Context APP;
private ITaskQueue mTaskQueue;
private List<ICmd> mCommands = new ArrayList<>();
private AriaManager(Context context) {
DbUtil.init(context.getApplicationContext());
APP = context;
DownloadTaskQueue.Builder builder = new DownloadTaskQueue.Builder(context);
mTaskQueue = builder.build();
regAppLifeCallback(context);
}
@ -90,8 +89,8 @@ import java.util.Map;
/**
* 获取任务队列
*/
public ITaskQueue getTaskQueue() {
return mTaskQueue;
public DownloadTaskQueue getTaskQueue() {
return mDTaskQueue;
}
/**
@ -193,7 +192,7 @@ import java.util.Map;
Log.w(TAG, "最大任务数不能小于 1");
return this;
}
mTaskQueue.setDownloadNum(maxDownloadNum);
mDTaskQueue.setDownloadNum(maxDownloadNum);
return this;
}
@ -247,6 +246,10 @@ import java.util.Map;
} else {
key = clsName;
}
} else if (obj instanceof Service) {
key = clsName;
} else if (obj instanceof Application) {
key = clsName;
}
} else {
key = clsName;

@ -16,10 +16,7 @@
package com.arialyy.aria.core.command;
import android.util.Log;
import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.core.inf.ITaskEntity;
import com.arialyy.aria.core.task.DownloadTask;
/**
* Created by lyy on 2016/8/22.

@ -16,9 +16,7 @@
package com.arialyy.aria.core.command;
import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.core.inf.ITaskEntity;
import com.arialyy.aria.core.task.DownloadTask;
/**
* Created by lyy on 2016/9/20.

@ -17,12 +17,9 @@
package com.arialyy.aria.core.command;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.core.inf.ITaskEntity;
import com.arialyy.aria.core.queue.ITaskQueue;
import com.arialyy.aria.core.inf.ICmd;
import com.arialyy.aria.core.task.DownloadTask;
import com.arialyy.aria.core.upload.UploadTaskEntity;
import com.arialyy.aria.util.CheckUtil;
import com.arialyy.aria.util.CommonUtil;

@ -16,9 +16,7 @@
package com.arialyy.aria.core.command;
import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.core.inf.ITaskEntity;
import com.arialyy.aria.core.task.DownloadTask;
/**
* Created by lyy on 2016/8/22.

@ -16,12 +16,7 @@
package com.arialyy.aria.core.command;
import android.text.TextUtils;
import android.util.Log;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.core.inf.ITaskEntity;
import com.arialyy.aria.core.task.DownloadTask;
/**
* Created by lyy on 2016/9/20.
@ -48,7 +43,7 @@ class StopCmd<T extends ITaskEntity> extends IDownloadCmd<T> {
//@Override public void executeCmd() {
// DownloadTask task = mQueue.getTask(mEntity.downloadEntity);
// if (task == null) {
// if (mEntity.downloadEntity.getState() == DownloadEntity.STATE_DOWNLOAD_ING) {
// if (mEntity.downloadEntity.getState() == DownloadEntity.STATE_RUNNING) {
// task = mQueue.createTask(mTargetName, mEntity);
// mQueue.stopTask(task);
// } else {

@ -13,9 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.aria.core.task;
package com.arialyy.aria.core.download;
import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.util.CAConfiguration;
import com.arialyy.aria.util.SSLContextUtil;
import java.io.IOException;

@ -19,6 +19,7 @@ package com.arialyy.aria.core.download;
import android.os.Parcel;
import android.os.Parcelable;
import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.inf.ITaskEntity;
import com.arialyy.aria.orm.Ignore;
import com.arialyy.aria.orm.DbEntity;
@ -29,43 +30,7 @@ import com.arialyy.aria.orm.DbEntity;
* 注意CREATOR要进行@Ignore注解
* 并且需要Parcelable时需要手动填写rowID;
*/
public class DownloadEntity extends DbEntity implements Parcelable{
/**
* 其它状态
*/
@Ignore public static final int STATE_OTHER = -1;
/**
* 失败状态
*/
@Ignore public static final int STATE_FAIL = 0;
/**
* 完成状态
*/
@Ignore public static final int STATE_COMPLETE = 1;
/**
* 停止状态
*/
@Ignore public static final int STATE_STOP = 2;
/**
* 未开始状态
*/
@Ignore public static final int STATE_WAIT = 3;
/**
* 下载中
*/
@Ignore public static final int STATE_DOWNLOAD_ING = 4;
/**
* 预处理
*/
@Ignore public static final int STATE_PRE = 5;
/**
* 预处理完成
*/
@Ignore public static final int STATE_POST_PRE = 6;
/**
* 取消下载
*/
@Ignore public static final int STATE_CANCEL = 7;
public class DownloadEntity extends DbEntity implements Parcelable, IEntity{
@Ignore public static final Creator<DownloadEntity> CREATOR = new Creator<DownloadEntity>() {
@Override public DownloadEntity createFromParcel(Parcel source) {
return new DownloadEntity(source);

@ -15,7 +15,7 @@
*/
package com.arialyy.aria.core.task;
package com.arialyy.aria.core.download;
class DownloadListener implements IDownloadListener {

@ -111,7 +111,7 @@ public class DownloadReceiver implements IReceiver {
List<DownloadEntity> allEntity = ariaManager.getAllDownloadEntity();
List<IDownloadCmd> stopCmds = new ArrayList<>();
for (DownloadEntity entity : allEntity) {
if (entity.getState() == DownloadEntity.STATE_DOWNLOAD_ING) {
if (entity.getState() == DownloadEntity.STATE_RUNNING) {
stopCmds.add(CommonUtil.createDownloadCmd(targetName, new DownloadTaskEntity(entity),
CmdFactory.TASK_STOP));
}

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.aria.core.task;
package com.arialyy.aria.core.download;
/**
* Created by lyy on 2017/1/18.

@ -14,17 +14,18 @@
* limitations under the License.
*/
package com.arialyy.aria.core.task;
package com.arialyy.aria.core.download;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.util.Log;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.inf.ITask;
import com.arialyy.aria.core.scheduler.DownloadSchedulers;
import com.arialyy.aria.core.scheduler.IDownloadSchedulers;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.util.CheckUtil;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.aria.util.Configuration;
@ -34,7 +35,7 @@ import java.lang.ref.WeakReference;
* Created by lyy on 2016/8/11.
* 下载任务类
*/
public class DownloadTask {
public class DownloadTask implements ITask {
public static final String TAG = "DownloadTask";
/**
* 产生该任务对象的hash码
@ -44,14 +45,14 @@ public class DownloadTask {
private DownloadTaskEntity mTaskEntity;
private IDownloadListener mListener;
private Handler mOutHandler;
private Context mContext;
private IDownloadUtil mUtil;
private Context mContext;
private DownloadTask(Context context, DownloadTaskEntity taskEntity, Handler outHandler) {
mContext = context.getApplicationContext();
private DownloadTask(DownloadTaskEntity taskEntity, Handler outHandler) {
mTaskEntity = taskEntity;
mEntity = taskEntity.downloadEntity;
mOutHandler = outHandler;
mContext = AriaManager.APP;
init();
}
@ -63,35 +64,57 @@ public class DownloadTask {
/**
* 获取下载速度
*/
public long getSpeed() {
@Override public long getSpeed() {
return mEntity.getSpeed();
}
/**
* 获取文件大小
*/
public long getFileSize() {
@Override public long getFileSize() {
return mEntity.getFileSize();
}
/**
* 获取当前下载进度
*/
public long getCurrentProgress() {
@Override public long getCurrentProgress() {
return mEntity.getCurrentProgress();
}
/**
* 获取当前下载任务的下载地址
*
* @see DownloadTask#getKey()
*/
public String getDownloadUrl() {
@Deprecated public String getDownloadUrl() {
return mEntity.getDownloadUrl();
}
@Override public String getKey() {
return getDownloadUrl();
}
/**
* 任务下载状态
*
* @see DownloadTask#isRunning()
*/
@Deprecated public boolean isDownloading() {
return mUtil.isDownloading();
}
@Override public boolean isRunning() {
return isDownloading();
}
@Override public IEntity getEntity() {
return mEntity;
}
/**
* 开始下载
*/
public void start() {
@Override public void start() {
if (mUtil.isDownloading()) {
Log.d(TAG, "任务正在下载");
} else {
@ -117,7 +140,7 @@ public class DownloadTask {
/**
* 停止下载
*/
public void stop() {
@Override public void stop() {
if (mUtil.isDownloading()) {
mUtil.stopDownload();
} else {
@ -134,17 +157,10 @@ public class DownloadTask {
}
}
/**
* 任务下载状态
*/
public boolean isDownloading() {
return mUtil.isDownloading();
}
/**
* 取消下载
*/
public void cancel() {
@Override public void cancel() {
if (mUtil.isDownloading()) {
mUtil.cancelDownload();
} else {
@ -166,18 +182,13 @@ public class DownloadTask {
static class Builder {
DownloadTaskEntity taskEntity;
Handler outHandler;
Context context;
int threadNum = 3;
String targetName;
public Builder(Context context, DownloadTaskEntity downloadEntity) {
this("", context, downloadEntity);
}
Builder(String targetName, Context context, DownloadTaskEntity taskEntity) {
Builder(String targetName, DownloadTaskEntity taskEntity) {
CheckUtil.checkDownloadEntity(taskEntity.downloadEntity);
this.targetName = targetName;
this.context = context;
this.taskEntity = taskEntity;
}
@ -200,7 +211,7 @@ public class DownloadTask {
}
public DownloadTask build() {
DownloadTask task = new DownloadTask(context, taskEntity, outHandler);
DownloadTask task = new DownloadTask(taskEntity, outHandler);
task.setTargetName(targetName);
taskEntity.downloadEntity.save();
return task;
@ -249,14 +260,14 @@ public class DownloadTask {
@Override public void onResume(long resumeLocation) {
super.onResume(resumeLocation);
downloadEntity.setState(DownloadEntity.STATE_DOWNLOAD_ING);
downloadEntity.setState(DownloadEntity.STATE_RUNNING);
sendInState2Target(DownloadSchedulers.RESUME);
sendIntent(Aria.ACTION_RESUME, resumeLocation);
}
@Override public void onStart(long startLocation) {
super.onStart(startLocation);
downloadEntity.setState(DownloadEntity.STATE_DOWNLOAD_ING);
downloadEntity.setState(DownloadEntity.STATE_RUNNING);
sendInState2Target(DownloadSchedulers.START);
sendIntent(Aria.ACTION_START, startLocation);
}

@ -14,10 +14,9 @@
* limitations under the License.
*/
package com.arialyy.aria.core.task;
package com.arialyy.aria.core.download;
import android.content.Context;
import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.core.scheduler.IDownloadSchedulers;
/**
@ -49,18 +48,17 @@ public class DownloadTaskFactory {
* @param entity 下载任务实体{@link DownloadTaskEntity}
* @param schedulers {@link IDownloadSchedulers}
*/
public DownloadTask createTask(Context context, DownloadTaskEntity entity,
IDownloadSchedulers schedulers) {
return createTask("", context, entity, schedulers);
public DownloadTask createTask(DownloadTaskEntity entity, IDownloadSchedulers schedulers) {
return createTask("", entity, schedulers);
}
/**
* @param entity 下载任务实体{@link DownloadTaskEntity}
* @param schedulers {@link IDownloadSchedulers}
*/
public DownloadTask createTask(String targetName, Context context, DownloadTaskEntity entity,
public DownloadTask createTask(String targetName, DownloadTaskEntity entity,
IDownloadSchedulers schedulers) {
DownloadTask.Builder builder = new DownloadTask.Builder(targetName, context, entity);
DownloadTask.Builder builder = new DownloadTask.Builder(targetName, entity);
builder.setOutHandler(schedulers);
return builder.build();
}

@ -14,18 +14,16 @@
* limitations under the License.
*/
package com.arialyy.aria.core.task;
package com.arialyy.aria.core.download;
import android.content.Context;
import android.util.Log;
import android.util.SparseArray;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.util.BufferedRandomAccessFile;
import com.arialyy.aria.util.CheckUtil;
import com.arialyy.aria.util.CommonUtil;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Properties;
@ -265,7 +263,8 @@ final class DownloadUtil implements IDownloadUtil, Runnable {
int fileLength = conn.getContentLength();
//必须建一个文件
CommonUtil.createFile(mDownloadFile.getPath());
RandomAccessFile file = new RandomAccessFile(mDownloadFile.getPath(), "rwd");
BufferedRandomAccessFile file =
new BufferedRandomAccessFile(new File(mDownloadFile.getPath()), "rwd", 8192);
//设置文件长度
file.setLength(fileLength);
mListener.onPostPre(fileLength);

@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.arialyy.aria.core.task;
package com.arialyy.aria.core.download;
/**
* 下载监听

@ -15,7 +15,7 @@
*/
package com.arialyy.aria.core.task;
package com.arialyy.aria.core.download;
/**
* Created by AriaLyy@outlook.com on 2016/10/31.

@ -13,14 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.aria.core.task;
package com.arialyy.aria.core.download;
import android.util.Log;
import com.arialyy.aria.util.BufferedRandomAccessFile;
import com.arialyy.aria.util.CommonUtil;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
@ -31,6 +31,7 @@ import java.util.Properties;
* 下载线程
*/
final class SingleThreadTask implements Runnable {
private static final int BUF_SIZE = 8192;
private static final String TAG = "SingleThreadTask";
private DownloadUtil.ConfigEntity mConfigEntity;
private String mConfigFPath;
@ -75,10 +76,11 @@ final class SingleThreadTask implements Runnable {
conn.setReadTimeout(mConstance.READ_TIME_OUT); //设置读取流的等待时间,必须设置该参数
is = conn.getInputStream();
//创建可设置位置的文件
RandomAccessFile file = new RandomAccessFile(mConfigEntity.TEMP_FILE, "rwd");
BufferedRandomAccessFile file =
new BufferedRandomAccessFile(mConfigEntity.TEMP_FILE, "rwd", BUF_SIZE);
//设置每条线程写入文件的位置
file.seek(mConfigEntity.START_LOCATION);
byte[] buffer = new byte[1024];
byte[] buffer = new byte[BUF_SIZE];
int len;
//当前子线程的下载位置
mChildCurrentLocation = mConfigEntity.START_LOCATION;

@ -0,0 +1,47 @@
package com.arialyy.aria.core.inf;
import com.arialyy.aria.orm.Ignore;
/**
* Created by Aria.Lao on 2017/2/23.
*/
public interface IEntity {
/**
* 其它状态
*/
@Ignore public static final int STATE_OTHER = -1;
/**
* 失败状态
*/
@Ignore public static final int STATE_FAIL = 0;
/**
* 完成状态
*/
@Ignore public static final int STATE_COMPLETE = 1;
/**
* 停止状态
*/
@Ignore public static final int STATE_STOP = 2;
/**
* 未开始状态
*/
@Ignore public static final int STATE_WAIT = 3;
/**
* 下载中
*/
@Ignore public static final int STATE_RUNNING = 4;
/**
* 预处理
*/
@Ignore public static final int STATE_PRE = 5;
/**
* 预处理完成
*/
@Ignore public static final int STATE_POST_PRE = 6;
/**
* 取消下载
*/
@Ignore public static final int STATE_CANCEL = 7;
}

@ -5,4 +5,32 @@ package com.arialyy.aria.core.inf;
*/
public interface ITask {
/**
* 唯一标识符DownloadTask 为下载地址UploadTask 为文件路径
*/
public String getKey();
/**
* 是否真正执行
* @return true正在执行
*/
public boolean isRunning();
/**
* 获取工具实体
*/
public IEntity getEntity();
public void start();
public void stop();
public void cancel();
public long getSpeed();
public long getFileSize();
public long getCurrentProgress();
}

@ -1,8 +1,9 @@
package com.arialyy.aria.core.inf;
/**
* Created by Aria.Lao on 2017/2/13.
* Created by Aria.Lao on 2017/2/23.
*/
public interface ITaskEntity {
}

@ -0,0 +1,17 @@
package com.arialyy.aria.core.queue;
import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.inf.ITask;
import com.arialyy.aria.core.inf.ITaskEntity;
import com.arialyy.aria.core.queue.pool.CachePool;
import com.arialyy.aria.core.queue.pool.ExecutePool;
/**
* Created by Aria.Lao on 2017/2/23.
*/
abstract class AbsTaskQueue<TASK extends ITask, TASK_ENTITY extends ITaskEntity, ENTITY extends IEntity>
implements ITaskQueue<TASK, TASK_ENTITY, ENTITY> {
CachePool<DownloadTask> mCachePool = new CachePool<>();
ExecutePool<DownloadTask> mExecutePool = new ExecutePool<>();
}

@ -16,35 +16,38 @@
package com.arialyy.aria.core.queue;
import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.queue.pool.CachePool;
import com.arialyy.aria.core.queue.pool.ExecutePool;
import com.arialyy.aria.core.scheduler.DownloadSchedulers;
import com.arialyy.aria.core.task.DownloadTask;
import com.arialyy.aria.core.task.DownloadTaskFactory;
import com.arialyy.aria.core.download.DownloadTaskFactory;
import com.arialyy.aria.util.Configuration;
/**
* Created by lyy on 2016/8/17.
* 下载任务队列
*/
public class DownloadTaskQueue implements ITaskQueue {
public class DownloadTaskQueue
extends AbsTaskQueue<DownloadTask, DownloadTaskEntity, DownloadEntity> {
private static final String TAG = "DownloadTaskQueue";
private CachePool mCachePool = CachePool.getInstance();
private ExecutePool mExecutePool = ExecutePool.getInstance();
private Context mContext;
//private IDownloadSchedulers mSchedulers;
private static volatile DownloadTaskQueue INSTANCE = null;
private static final Object LOCK = new Object();
private DownloadTaskQueue() {
public static DownloadTaskQueue getInstance() {
if (INSTANCE == null) {
synchronized (LOCK) {
INSTANCE = new DownloadTaskQueue();
}
}
return INSTANCE;
}
private DownloadTaskQueue(Context context) {
super();
mContext = context;
private DownloadTaskQueue() {
}
/**
@ -88,7 +91,7 @@ public class DownloadTaskQueue implements ITaskQueue {
}
@Override public void stopTask(DownloadTask task) {
if (!task.isDownloading()) Log.w(TAG, "停止任务失败,【任务已经停止】");
if (!task.isRunning()) Log.w(TAG, "停止任务失败,【任务已经停止】");
if (mExecutePool.removeTask(task)) {
task.stop();
} else {
@ -106,7 +109,7 @@ public class DownloadTaskQueue implements ITaskQueue {
Log.w(TAG, "重试下载失败,task 为null");
return;
}
if (!task.isDownloading()) {
if (!task.isRunning()) {
task.start();
} else {
Log.w(TAG, "任务没有完全停止,重试下载失败");
@ -138,8 +141,7 @@ public class DownloadTaskQueue implements ITaskQueue {
if (diff >= 1) {
for (int i = 0; i < diff; i++) {
DownloadTask nextTask = getNextTask();
if (nextTask != null
&& nextTask.getDownloadEntity().getState() == DownloadEntity.STATE_WAIT) {
if (nextTask != null && nextTask.getDownloadEntity().getState() == IEntity.STATE_WAIT) {
startTask(nextTask);
}
}
@ -149,11 +151,10 @@ public class DownloadTaskQueue implements ITaskQueue {
@Override public DownloadTask createTask(String target, DownloadTaskEntity entity) {
DownloadTask task;
if (TextUtils.isEmpty(target)) {
task =
DownloadTaskFactory.getInstance().createTask(mContext, entity, DownloadSchedulers.getInstance());
task = DownloadTaskFactory.getInstance().createTask(entity, DownloadSchedulers.getInstance());
} else {
task = DownloadTaskFactory.getInstance()
.createTask(target, mContext, entity, DownloadSchedulers.getInstance());
.createTask(target, entity, DownloadSchedulers.getInstance());
}
mCachePool.putTask(task);
return task;
@ -181,17 +182,4 @@ public class DownloadTaskQueue implements ITaskQueue {
@Override public DownloadTask getNextTask() {
return mCachePool.pollTask();
}
public static class Builder {
Context context;
public Builder(Context context) {
this.context = context.getApplicationContext();
}
public DownloadTaskQueue build() {
DownloadTaskQueue queue = new DownloadTaskQueue(context);
return queue;
}
}
}

@ -1,54 +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.core.queue;
import com.arialyy.aria.core.task.DownloadTask;
/**
* Created by lyy on 2016/8/16.
* 下载功能接口
*/
public interface IDownloader {
/**
* 开始任务
*
* @param task {@link DownloadTask}
*/
public void startTask(DownloadTask task);
/**
* 停止任务
*
* @param task {@link DownloadTask}
*/
public void stopTask(DownloadTask task);
/**
* 取消任务
*
* @param task {@link DownloadTask}
*/
public void cancelTask(DownloadTask task);
/**
* 重试下载
*
* @param task {@link DownloadTask}
*/
public void reTryStart(DownloadTask task);
}

@ -17,24 +17,24 @@
package com.arialyy.aria.core.queue;
import com.arialyy.aria.core.task.DownloadTask;
import com.arialyy.aria.core.inf.ITask;
/**
* Created by lyy on 2016/8/14.
* 任务池
*/
public interface IPool {
public interface IPool<T extends ITask> {
/**
* 将下载任务添加到任务池中
*/
public boolean putTask(DownloadTask task);
public boolean putTask(T task);
/**
* 按照队列原则取出下载任务
*
* @return 返回null或者下载任务
*/
public DownloadTask pollTask();
public T pollTask();
/**
* 通过下载链接获取下载任务当任务不为空时队列将删除该下载任务
@ -42,7 +42,7 @@ public interface IPool {
* @param downloadUrl 下载链接
* @return 返回null或者下载任务
*/
public DownloadTask getTask(String downloadUrl);
public T getTask(String downloadUrl);
/**
* 删除任务池中的下载任务
@ -50,7 +50,7 @@ public interface IPool {
* @param task 下载任务
* @return true:移除成功
*/
public boolean removeTask(DownloadTask task);
public boolean removeTask(T task);
/**
* 通过下载链接移除下载任务

@ -18,13 +18,44 @@ package com.arialyy.aria.core.queue;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.core.task.DownloadTask;
import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.inf.ITask;
import com.arialyy.aria.core.inf.ITaskEntity;
/**
* Created by lyy on 2016/8/16.
* 任务功能接口
*/
public interface ITaskQueue extends IDownloader {
public interface ITaskQueue<TASK extends ITask, TASK_ENTITY extends ITaskEntity, ENTITY extends IEntity> {
/**
* 开始任务
*
* @param task {@link DownloadTask}
*/
public void startTask(TASK task);
/**
* 停止任务
*
* @param task {@link DownloadTask}
*/
public void stopTask(TASK task);
/**
* 取消任务
*
* @param task {@link DownloadTask}
*/
public void cancelTask(TASK task);
/**
* 重试下载
*
* @param task {@link DownloadTask}
*/
public void reTryStart(TASK task);
/**
* 任务池队列大小
@ -45,7 +76,7 @@ public interface ITaskQueue extends IDownloader {
* @param targetName 生成该任务的对象
* @return {@link DownloadTask}
*/
public DownloadTask createTask(String targetName, DownloadTaskEntity entity);
public TASK createTask(String targetName, TASK_ENTITY entity);
/**
* 通过下载链接从缓存池或任务池搜索下载任务如果缓存池或任务池都没有任务则创建新任务
@ -53,19 +84,19 @@ public interface ITaskQueue extends IDownloader {
* @param entity 下载实体{@link DownloadEntity}
* @return {@link DownloadTask}
*/
public DownloadTask getTask(DownloadEntity entity);
public TASK getTask(ENTITY entity);
/**
* 通过下载链接删除任务
*
* @param entity 下载实体{@link DownloadEntity}
*/
public void removeTask(DownloadEntity entity);
public void removeTask(ENTITY entity);
/**
* 获取缓存池的下一个任务
*
* @return 下载任务 or null
*/
public DownloadTask getNextTask();
public TASK getNextTask();
}

@ -18,8 +18,8 @@ package com.arialyy.aria.core.queue.pool;
import android.text.TextUtils;
import android.util.Log;
import com.arialyy.aria.core.inf.ITask;
import com.arialyy.aria.core.queue.IPool;
import com.arialyy.aria.core.task.DownloadTask;
import com.arialyy.aria.util.CommonUtil;
import java.util.HashMap;
import java.util.Map;
@ -30,36 +30,36 @@ import java.util.concurrent.TimeUnit;
* Created by lyy on 2016/8/14.
* 任务缓存池所有下载任务最先缓存在这个池中
*/
public class CachePool implements IPool {
public class CachePool<TASK extends ITask> implements IPool<TASK> {
private static final String TAG = "CachePool";
private static final Object LOCK = new Object();
private static final int MAX_NUM = Integer.MAX_VALUE; //最大下载任务数
private static volatile CachePool INSTANCE = null;
private static final long TIME_OUT = 1000;
private Map<String, DownloadTask> mCacheArray;
private LinkedBlockingQueue<DownloadTask> mCacheQueue;
private Map<String, TASK> mCacheArray;
private LinkedBlockingQueue<TASK> mCacheQueue;
private CachePool() {
public CachePool() {
mCacheQueue = new LinkedBlockingQueue<>(MAX_NUM);
mCacheArray = new HashMap<>();
}
public static CachePool getInstance() {
if (INSTANCE == null) {
synchronized (LOCK) {
INSTANCE = new CachePool();
}
}
return INSTANCE;
}
//public static CachePool getInstance() {
// if (INSTANCE == null) {
// synchronized (LOCK) {
// INSTANCE = new CachePool();
// }
// }
// return INSTANCE;
//}
@Override public boolean putTask(DownloadTask task) {
@Override public boolean putTask(TASK task) {
synchronized (LOCK) {
if (task == null) {
Log.e(TAG, "下载任务不能为空!!");
return false;
}
String url = task.getDownloadEntity().getDownloadUrl();
String url = task.getKey();
if (mCacheQueue.contains(task)) {
Log.w(TAG, "队列中已经包含了该任务,任务下载链接【" + url + "】");
return false;
@ -74,13 +74,13 @@ public class CachePool implements IPool {
}
}
@Override public DownloadTask pollTask() {
@Override public TASK pollTask() {
synchronized (LOCK) {
try {
DownloadTask task = null;
TASK task = null;
task = mCacheQueue.poll(TIME_OUT, TimeUnit.MICROSECONDS);
if (task != null) {
String url = task.getDownloadEntity().getDownloadUrl();
String url = task.getKey();
mCacheArray.remove(CommonUtil.keyToHashKey(url));
}
return task;
@ -91,7 +91,7 @@ public class CachePool implements IPool {
return null;
}
@Override public DownloadTask getTask(String downloadUrl) {
@Override public TASK getTask(String downloadUrl) {
synchronized (LOCK) {
if (TextUtils.isEmpty(downloadUrl)) {
Log.e(TAG, "请传入有效的下载链接");
@ -102,13 +102,13 @@ public class CachePool implements IPool {
}
}
@Override public boolean removeTask(DownloadTask task) {
@Override public boolean removeTask(TASK task) {
synchronized (LOCK) {
if (task == null) {
Log.e(TAG, "任务不能为空");
return false;
} else {
String key = CommonUtil.keyToHashKey(task.getDownloadEntity().getDownloadUrl());
String key = CommonUtil.keyToHashKey(task.getKey());
mCacheArray.remove(key);
return mCacheQueue.remove(task);
}
@ -122,7 +122,7 @@ public class CachePool implements IPool {
return false;
}
String key = CommonUtil.keyToHashKey(downloadUrl);
DownloadTask task = mCacheArray.get(key);
TASK task = mCacheArray.get(key);
mCacheArray.remove(key);
return mCacheQueue.remove(task);
}

@ -18,9 +18,9 @@ package com.arialyy.aria.core.queue.pool;
import android.text.TextUtils;
import android.util.Log;
import com.arialyy.aria.core.task.DownloadTask;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.aria.core.inf.ITask;
import com.arialyy.aria.core.queue.IPool;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.aria.util.Configuration;
import java.util.HashMap;
import java.util.Map;
@ -31,37 +31,37 @@ import java.util.concurrent.TimeUnit;
* Created by lyy on 2016/8/15.
* 任务执行池所有当前下载任务都该任务池中默认下载大小为2
*/
public class ExecutePool implements IPool {
public class ExecutePool<TASK extends ITask> implements IPool<TASK> {
private static final String TAG = "ExecutePool";
private static final Object LOCK = new Object();
private static final long TIME_OUT = 1000;
private static volatile ExecutePool INSTANCE = null;
private ArrayBlockingQueue<DownloadTask> mExecuteQueue;
private Map<String, DownloadTask> mExecuteArray;
private ArrayBlockingQueue<TASK> mExecuteQueue;
private Map<String, TASK> mExecuteArray;
private int mSize;
private ExecutePool() {
public ExecutePool() {
mSize = Configuration.getInstance().getDownloadNum();
mExecuteQueue = new ArrayBlockingQueue<>(mSize);
mExecuteArray = new HashMap<>();
}
public static ExecutePool getInstance() {
if (INSTANCE == null) {
synchronized (LOCK) {
INSTANCE = new ExecutePool();
}
}
return INSTANCE;
}
//public static ExecutePool getInstance() {
// if (INSTANCE == null) {
// synchronized (LOCK) {
// INSTANCE = new ExecutePool();
// }
// }
// return INSTANCE;
//}
@Override public boolean putTask(DownloadTask task) {
@Override public boolean putTask(TASK task) {
synchronized (LOCK) {
if (task == null) {
Log.e(TAG, "下载任务不能为空!!");
return false;
}
String url = task.getDownloadEntity().getDownloadUrl();
String url = task.getKey();
if (mExecuteQueue.contains(task)) {
Log.e(TAG, "队列中已经包含了该任务,任务下载链接【" + url + "】");
return false;
@ -85,8 +85,8 @@ public class ExecutePool implements IPool {
*/
public void setDownloadNum(int downloadNum) {
try {
ArrayBlockingQueue<DownloadTask> temp = new ArrayBlockingQueue<>(downloadNum);
DownloadTask task;
ArrayBlockingQueue<TASK> temp = new ArrayBlockingQueue<>(downloadNum);
TASK task;
while ((task = mExecuteQueue.poll(TIME_OUT, TimeUnit.MICROSECONDS)) != null) {
temp.offer(task);
}
@ -103,8 +103,8 @@ public class ExecutePool implements IPool {
*
* @param newTask 新下载任务
*/
private boolean putNewTask(DownloadTask newTask) {
String url = newTask.getDownloadEntity().getDownloadUrl();
private boolean putNewTask(TASK newTask) {
String url = newTask.getKey();
boolean s = mExecuteQueue.offer(newTask);
Log.w(TAG, "任务添加" + (s ? "成功" : "失败,【" + url + "】"));
if (s) {
@ -119,14 +119,14 @@ public class ExecutePool implements IPool {
*/
private boolean pollFirstTask() {
try {
DownloadTask oldTask = mExecuteQueue.poll(TIME_OUT, TimeUnit.MICROSECONDS);
TASK oldTask = mExecuteQueue.poll(TIME_OUT, TimeUnit.MICROSECONDS);
if (oldTask == null) {
Log.e(TAG, "移除任务失败");
return false;
}
oldTask.stop();
// wait(200);
String key = CommonUtil.keyToHashKey(oldTask.getDownloadEntity().getDownloadUrl());
String key = CommonUtil.keyToHashKey(oldTask.getKey());
mExecuteArray.remove(key);
} catch (InterruptedException e) {
e.printStackTrace();
@ -135,13 +135,13 @@ public class ExecutePool implements IPool {
return true;
}
@Override public DownloadTask pollTask() {
@Override public TASK pollTask() {
synchronized (LOCK) {
try {
DownloadTask task = null;
TASK task = null;
task = mExecuteQueue.poll(TIME_OUT, TimeUnit.MICROSECONDS);
if (task != null) {
String url = task.getDownloadEntity().getDownloadUrl();
String url = task.getKey();
mExecuteArray.remove(CommonUtil.keyToHashKey(url));
}
return task;
@ -152,7 +152,7 @@ public class ExecutePool implements IPool {
}
}
@Override public DownloadTask getTask(String downloadUrl) {
@Override public TASK getTask(String downloadUrl) {
synchronized (LOCK) {
if (TextUtils.isEmpty(downloadUrl)) {
Log.e(TAG, "请传入有效的下载链接");
@ -163,13 +163,13 @@ public class ExecutePool implements IPool {
}
}
@Override public boolean removeTask(DownloadTask task) {
@Override public boolean removeTask(TASK task) {
synchronized (LOCK) {
if (task == null) {
Log.e(TAG, "任务不能为空");
return false;
} else {
String key = CommonUtil.keyToHashKey(task.getDownloadEntity().getDownloadUrl());
String key = CommonUtil.keyToHashKey(task.getKey());
mExecuteArray.remove(key);
return mExecuteQueue.remove(task);
}
@ -183,7 +183,7 @@ public class ExecutePool implements IPool {
return false;
}
String key = CommonUtil.keyToHashKey(downloadUrl);
DownloadTask task = mExecuteArray.get(key);
TASK task = mExecuteArray.get(key);
mExecuteArray.remove(key);
return mExecuteQueue.remove(task);
}

@ -22,7 +22,7 @@ import android.util.Log;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.queue.ITaskQueue;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.task.DownloadTask;
import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.aria.util.Configuration;
import java.util.Iterator;
import java.util.Map;

@ -15,7 +15,7 @@
*/
package com.arialyy.aria.core.scheduler;
import com.arialyy.aria.core.task.DownloadTask;
import com.arialyy.aria.core.download.DownloadTask;
/**
* Target处理任务监听

@ -1,13 +1,14 @@
package com.arialyy.aria.core.upload;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.orm.DbEntity;
/**
* Created by Aria.Lao on 2017/2/9.
* 上传文件实体
*/
public class UploadEntity {
public class UploadEntity implements IEntity{
private String filePath; //文件路径
private String fileName; //文件名
@ -28,4 +29,5 @@ public class UploadEntity {
public void setFileName(String fileName) {
this.fileName = fileName;
}
}

@ -0,0 +1,39 @@
package com.arialyy.aria.core.upload;
/**
* Created by Aria.Lao on 2017/2/23.
*/
public class UploadListener implements IUploadListener{
@Override public void onPre() {
}
@Override public void onStart(long fileSize) {
}
@Override public void onResume(long resumeLocation) {
}
@Override public void onStop(long stopLocation) {
}
@Override public void onProgress(long currentLocation) {
}
@Override public void onCancel() {
}
@Override public void onComplete() {
}
@Override public void onFail() {
}
}

@ -0,0 +1,114 @@
package com.arialyy.aria.core.upload;
import android.os.Handler;
import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.inf.ITask;
/**
* Created by Aria.Lao on 2017/2/23.
* 上传任务
*/
public class UploadTask implements ITask {
private Handler mOutHandler;
private UploadTaskEntity mTaskEntity;
private UploadEntity mUploadEntity;
UploadTask(UploadTaskEntity taskEntity, Handler outHandler) {
mTaskEntity = taskEntity;
mOutHandler = outHandler;
mUploadEntity = mTaskEntity.uploadEntity;
}
@Override public String getKey() {
return null;
}
@Override public boolean isRunning() {
return false;
}
@Override public IEntity getEntity() {
return mUploadEntity;
}
@Override public void start() {
}
@Override public void stop() {
}
@Override public void cancel() {
}
@Override public long getSpeed() {
return 0;
}
@Override public long getFileSize() {
return 0;
}
@Override public long getCurrentProgress() {
return 0;
}
private static class UListener extends UploadListener{
@Override public void onPre() {
}
@Override public void onStart(long fileSize) {
}
@Override public void onResume(long resumeLocation) {
}
@Override public void onStop(long stopLocation) {
}
@Override public void onProgress(long currentLocation) {
}
@Override public void onCancel() {
}
@Override public void onComplete() {
}
@Override public void onFail() {
}
}
static class Builder {
private Handler mOutHandler;
private UploadTaskEntity mTaskEntity;
public void setOutHandler(Handler outHandler){
mOutHandler = outHandler;
}
public void setUploadTaskEntity(UploadTaskEntity taskEntity){
mTaskEntity = taskEntity;
}
public Builder(){
}
public UploadTask build(){
UploadTask task = new UploadTask(mTaskEntity, mOutHandler);
return task;
}
}
}

@ -0,0 +1,49 @@
package com.arialyy.aria.core.upload;
import com.arialyy.aria.core.queue.ITaskQueue;
/**
* Created by Aria.Lao on 2017/2/23.
*/
public class UploadTaskQueue implements ITaskQueue<UploadTask, UploadTaskEntity, UploadEntity>{
@Override public void startTask(UploadTask task) {
}
@Override public void stopTask(UploadTask task) {
}
@Override public void cancelTask(UploadTask task) {
}
@Override public void reTryStart(UploadTask task) {
}
@Override public int size() {
return 0;
}
@Override public void setDownloadNum(int downloadNum) {
}
@Override public UploadTask createTask(String targetName, UploadTaskEntity entity) {
return null;
}
@Override public UploadTask getTask(UploadEntity entity) {
return null;
}
@Override public void removeTask(UploadEntity entity) {
}
@Override public UploadTask getNextTask() {
return null;
}
}

@ -0,0 +1,331 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.util;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Arrays;
//import org.apache.log4j.Logger;
/**
* A <code>BufferedRandomAccessFile</code> is like a
* <code>RandomAccessFile</code>, but it uses a private buffer so that most
* operations do not require a disk access.
* <P>
*
* Note: The operations on this class are unmonitored. Also, the correct
* functioning of the <code>RandomAccessFile</code> methods that are not
* overridden here relies on the implementation of those methods in the
* superclass.
* Author : Avinash Lakshman ( alakshman@facebook.com) Prashant Malik ( pmalik@facebook.com )
*/
public final class BufferedRandomAccessFile extends RandomAccessFile {
//private static final Logger logger_ = Logger.getLogger(BufferedRandomAccessFile.class);
static final int LogBuffSz_ = 16; // 64K buffer
public static final int BuffSz_ = (1 << LogBuffSz_);
static final long BuffMask_ = ~(((long) BuffSz_) - 1L);
/*
* This implementation is based on the buffer implementation in Modula-3's
* "Rd", "Wr", "RdClass", and "WrClass" interfaces.
*/
private boolean dirty_; // true iff unflushed bytes exist
private boolean closed_; // true iff the file is closed
private long curr_; // current position in file
private long lo_, hi_; // bounds on characters in "buff"
private byte[] buff_; // local buffer
private long maxHi_; // this.lo + this.buff.length
private boolean hitEOF_; // buffer contains last file block?
private long diskPos_; // disk position
/*
* To describe the above fields, we introduce the following abstractions for
* the file "f":
*
* len(f) the length of the file curr(f) the current position in the file
* c(f) the abstract contents of the file disk(f) the contents of f's
* backing disk file closed(f) true iff the file is closed
*
* "curr(f)" is an index in the closed interval [0, len(f)]. "c(f)" is a
* character sequence of length "len(f)". "c(f)" and "disk(f)" may differ if
* "c(f)" contains unflushed writes not reflected in "disk(f)". The flush
* operation has the effect of making "disk(f)" identical to "c(f)".
*
* A file is said to be *valid* if the following conditions hold:
*
* V1. The "closed" and "curr" fields are correct:
*
* f.closed == closed(f) f.curr == curr(f)
*
* V2. The current position is either contained in the buffer, or just past
* the buffer:
*
* f.lo <= f.curr <= f.hi
*
* V3. Any (possibly) unflushed characters are stored in "f.buff":
*
* (forall i in [f.lo, f.curr): c(f)[i] == f.buff[i - f.lo])
*
* V4. For all characters not covered by V3, c(f) and disk(f) agree:
*
* (forall i in [f.lo, len(f)): i not in [f.lo, f.curr) => c(f)[i] ==
* disk(f)[i])
*
* V5. "f.dirty" is true iff the buffer contains bytes that should be
* flushed to the file; by V3 and V4, only part of the buffer can be dirty.
*
* f.dirty == (exists i in [f.lo, f.curr): c(f)[i] != f.buff[i - f.lo])
*
* V6. this.maxHi == this.lo + this.buff.length
*
* Note that "f.buff" can be "null" in a valid file, since the range of
* characters in V3 is empty when "f.lo == f.curr".
*
* A file is said to be *ready* if the buffer contains the current position,
* i.e., when:
*
* R1. !f.closed && f.buff != null && f.lo <= f.curr && f.curr < f.hi
*
* When a file is ready, reading or writing a single byte can be performed
* by reading or writing the in-memory buffer without performing a disk
* operation.
*/
/**
* Open a new <code>BufferedRandomAccessFile</code> on <code>file</code>
* in mode <code>mode</code>, which should be "r" for reading only, or
* "rw" for reading and writing.
*/
public BufferedRandomAccessFile(File file, String mode) throws IOException {
super(file, mode);
this.init(0);
}
public BufferedRandomAccessFile(File file, String mode, int size) throws IOException {
super(file, mode);
this.init(size);
}
/**
* Open a new <code>BufferedRandomAccessFile</code> on the file named
* <code>name</code> in mode <code>mode</code>, which should be "r" for
* reading only, or "rw" for reading and writing.
*/
public BufferedRandomAccessFile(String name, String mode) throws IOException {
super(name, mode);
this.init(0);
}
public BufferedRandomAccessFile(String name, String mode, int size) throws FileNotFoundException {
super(name, mode);
this.init(size);
}
private void init(int size) {
this.dirty_ = this.closed_ = false;
this.lo_ = this.curr_ = this.hi_ = 0;
this.buff_ = (size > BuffSz_) ? new byte[size] : new byte[BuffSz_];
this.maxHi_ = (long) BuffSz_;
this.hitEOF_ = false;
this.diskPos_ = 0L;
}
public void close() throws IOException {
this.flush();
this.closed_ = true;
super.close();
}
/**
* Flush any bytes in the file's buffer that have not yet been written to
* disk. If the file was created read-only, this method is a no-op.
*/
public void flush() throws IOException {
this.flushBuffer();
}
/* Flush any dirty bytes in the buffer to disk. */
private void flushBuffer() throws IOException {
if (this.dirty_) {
if (this.diskPos_ != this.lo_) super.seek(this.lo_);
int len = (int) (this.curr_ - this.lo_);
super.write(this.buff_, 0, len);
this.diskPos_ = this.curr_;
this.dirty_ = false;
}
}
/*
* Read at most "this.buff.length" bytes into "this.buff", returning the
* number of bytes read. If the return result is less than
* "this.buff.length", then EOF was read.
*/
private int fillBuffer() throws IOException {
int cnt = 0;
int rem = this.buff_.length;
while (rem > 0) {
int n = super.read(this.buff_, cnt, rem);
if (n < 0) break;
cnt += n;
rem -= n;
}
if ((cnt < 0) && (this.hitEOF_ = (cnt < this.buff_.length))) {
// make sure buffer that wasn't read is initialized with -1
Arrays.fill(this.buff_, cnt, this.buff_.length, (byte) 0xff);
}
this.diskPos_ += cnt;
return cnt;
}
/*
* This method positions <code>this.curr</code> at position <code>pos</code>.
* If <code>pos</code> does not fall in the current buffer, it flushes the
* current buffer and loads the correct one.<p>
*
* On exit from this routine <code>this.curr == this.hi</code> iff <code>pos</code>
* is at or past the end-of-file, which can only happen if the file was
* opened in read-only mode.
*/
public void seek(long pos) throws IOException {
if (pos >= this.hi_ || pos < this.lo_) {
// seeking outside of current buffer -- flush and read
this.flushBuffer();
this.lo_ = pos & BuffMask_; // start at BuffSz boundary
this.maxHi_ = this.lo_ + (long) this.buff_.length;
if (this.diskPos_ != this.lo_) {
super.seek(this.lo_);
this.diskPos_ = this.lo_;
}
int n = this.fillBuffer();
this.hi_ = this.lo_ + (long) n;
} else {
// seeking inside current buffer -- no read required
if (pos < this.curr_) {
// if seeking backwards, we must flush to maintain V4
this.flushBuffer();
}
}
this.curr_ = pos;
}
public long getFilePointer() {
return this.curr_;
}
public long length() throws IOException {
return Math.max(this.curr_, super.length());
}
public int read() throws IOException {
if (this.curr_ >= this.hi_) {
// test for EOF
// if (this.hi < this.maxHi) return -1;
if (this.hitEOF_) return -1;
// slow path -- read another buffer
this.seek(this.curr_);
if (this.curr_ == this.hi_) return -1;
}
byte res = this.buff_[(int) (this.curr_ - this.lo_)];
this.curr_++;
return ((int) res) & 0xFF; // convert byte -> int
}
public int read(byte[] b) throws IOException {
return this.read(b, 0, b.length);
}
public int read(byte[] b, int off, int len) throws IOException {
if (this.curr_ >= this.hi_) {
// test for EOF
// if (this.hi < this.maxHi) return -1;
if (this.hitEOF_) return -1;
// slow path -- read another buffer
this.seek(this.curr_);
if (this.curr_ == this.hi_) return -1;
}
len = Math.min(len, (int) (this.hi_ - this.curr_));
int buffOff = (int) (this.curr_ - this.lo_);
System.arraycopy(this.buff_, buffOff, b, off, len);
this.curr_ += len;
return len;
}
public void write(int b) throws IOException {
if (this.curr_ >= this.hi_) {
if (this.hitEOF_ && this.hi_ < this.maxHi_) {
// at EOF -- bump "hi"
this.hi_++;
} else {
// slow path -- write current buffer; read next one
this.seek(this.curr_);
if (this.curr_ == this.hi_) {
// appending to EOF -- bump "hi"
this.hi_++;
}
}
}
this.buff_[(int) (this.curr_ - this.lo_)] = (byte) b;
this.curr_++;
this.dirty_ = true;
}
public void write(byte[] b) throws IOException {
this.write(b, 0, b.length);
}
public void write(byte[] b, int off, int len) throws IOException {
while (len > 0) {
int n = this.writeAtMost(b, off, len);
off += n;
len -= n;
this.dirty_ = true;
}
}
/*
* Write at most "len" bytes to "b" starting at position "off", and return
* the number of bytes written.
*/
private int writeAtMost(byte[] b, int off, int len) throws IOException {
if (this.curr_ >= this.hi_) {
if (this.hitEOF_ && this.hi_ < this.maxHi_) {
// at EOF -- bump "hi"
this.hi_ = this.maxHi_;
} else {
// slow path -- write current buffer; read next one
this.seek(this.curr_);
if (this.curr_ == this.hi_) {
// appending to EOF -- bump "hi"
this.hi_ = this.maxHi_;
}
}
}
len = Math.min(len, (int) (this.hi_ - this.curr_));
int buffOff = (int) (this.curr_ - this.lo_);
System.arraycopy(b, off, this.buff_, buffOff, len);
this.curr_ += len;
return len;
}
}

@ -10,7 +10,7 @@ import butterknife.OnClick;
import com.arialyy.aria.core.download.DownloadTarget;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.task.DownloadTask;
import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.frame.core.AbsDialog;
import com.arialyy.simple.R;
@ -50,7 +50,7 @@ public class DownloadDialog extends AbsDialog {
if (entity != null) {
mSize.setText(CommonUtil.formatFileSize(entity.getFileSize()));
int state = entity.getState();
setBtState(state != DownloadEntity.STATE_DOWNLOAD_ING);
setBtState(state != DownloadEntity.STATE_RUNNING);
} else {
setBtState(true);
}

@ -10,7 +10,7 @@ import butterknife.OnClick;
import com.arialyy.aria.core.download.DownloadTarget;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.task.DownloadTask;
import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.frame.core.AbsFragment;
import com.arialyy.simple.R;
@ -41,7 +41,7 @@ public class DownloadFragment extends AbsFragment<FragmentDownloadBinding> {
if (entity != null) {
mSize.setText(CommonUtil.formatFileSize(entity.getFileSize()));
int state = entity.getState();
setBtState(state != DownloadEntity.STATE_DOWNLOAD_ING);
setBtState(state != DownloadEntity.STATE_RUNNING);
} else {
setBtState(true);
}

@ -5,7 +5,7 @@ import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import butterknife.Bind;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.task.DownloadTask;
import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.frame.util.show.L;
import com.arialyy.simple.R;
import com.arialyy.simple.base.BaseActivity;

@ -125,7 +125,7 @@ final class DownloadAdapter extends AbsRVAdapter<DownloadEntity, DownloadAdapter
break;
case DownloadEntity.STATE_PRE:
case DownloadEntity.STATE_POST_PRE:
case DownloadEntity.STATE_DOWNLOAD_ING:
case DownloadEntity.STATE_RUNNING:
str = "暂停";
color = android.R.color.holo_red_light;
break;
@ -176,7 +176,7 @@ final class DownloadAdapter extends AbsRVAdapter<DownloadEntity, DownloadAdapter
case DownloadEntity.STATE_COMPLETE:
start(entity);
break;
case DownloadEntity.STATE_DOWNLOAD_ING:
case DownloadEntity.STATE_RUNNING:
stop(entity);
break;
}

@ -24,7 +24,7 @@ import android.support.v7.widget.Toolbar;
import android.view.View;
import butterknife.Bind;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.task.DownloadTask;
import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.simple.R;
import com.arialyy.simple.base.BaseActivity;
import com.arialyy.simple.databinding.ActivityMultiBinding;

@ -5,7 +5,7 @@ import android.content.Context;
import android.os.Environment;
import android.support.v4.app.NotificationCompat;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.task.DownloadTask;
import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.simple.R;
/**

@ -12,7 +12,7 @@ import butterknife.OnClick;
import com.arialyy.aria.core.download.DownloadTarget;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.task.DownloadTask;
import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.frame.core.AbsPopupWindow;
import com.arialyy.simple.R;
@ -52,7 +52,7 @@ public class DownloadPopupWindow extends AbsPopupWindow {
if (entity != null) {
mSize.setText(CommonUtil.formatFileSize(entity.getFileSize()));
int state = entity.getState();
setBtState(state != DownloadEntity.STATE_DOWNLOAD_ING);
setBtState(state != DownloadEntity.STATE_RUNNING);
} else {
setBtState(true);
}

@ -33,7 +33,7 @@ import butterknife.Bind;
import com.arialyy.aria.core.download.DownloadTarget;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.task.DownloadTask;
import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.frame.util.show.L;
import com.arialyy.simple.R;

Loading…
Cancel
Save