修复下载速度慢的问题
This commit is contained in:
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@ -37,7 +37,7 @@
|
|||||||
<ConfirmationsSetting value="0" id="Add" />
|
<ConfirmationsSetting value="0" id="Add" />
|
||||||
<ConfirmationsSetting value="0" id="Remove" />
|
<ConfirmationsSetting value="0" id="Remove" />
|
||||||
</component>
|
</component>
|
||||||
<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">
|
<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">
|
||||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectType">
|
<component name="ProjectType">
|
||||||
|
@ -69,6 +69,7 @@ class ConnectionHelp {
|
|||||||
"image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*");
|
"image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*");
|
||||||
////用于处理Disconnect 不起作用问题
|
////用于处理Disconnect 不起作用问题
|
||||||
//conn.setRequestProperty("Connection", "close");
|
//conn.setRequestProperty("Connection", "close");
|
||||||
|
conn.setRequestProperty("Connection", "Keep-Alive");
|
||||||
return conn;
|
return conn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ import android.content.Context;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
import com.arialyy.aria.core.DownloadEntity;
|
import com.arialyy.aria.core.DownloadEntity;
|
||||||
|
import com.arialyy.aria.util.BufferedRandomAccessFile;
|
||||||
import com.arialyy.aria.util.CommonUtil;
|
import com.arialyy.aria.util.CommonUtil;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -34,7 +35,7 @@ import java.util.concurrent.Executors;
|
|||||||
* Created by lyy on 2015/8/25.
|
* Created by lyy on 2015/8/25.
|
||||||
* 下载工具类
|
* 下载工具类
|
||||||
*/
|
*/
|
||||||
final class DownloadUtil implements IDownloadUtil, Runnable {
|
public class DownloadUtil implements IDownloadUtil, Runnable {
|
||||||
private static final String TAG = "DownloadUtil";
|
private static final String TAG = "DownloadUtil";
|
||||||
/**
|
/**
|
||||||
* 线程数
|
* 线程数
|
||||||
@ -54,7 +55,7 @@ final class DownloadUtil implements IDownloadUtil, Runnable {
|
|||||||
private SparseArray<Runnable> mTask = new SparseArray<>();
|
private SparseArray<Runnable> mTask = new SparseArray<>();
|
||||||
private DownloadStateConstance mConstance;
|
private DownloadStateConstance mConstance;
|
||||||
|
|
||||||
DownloadUtil(Context context, DownloadEntity entity, IDownloadListener downloadListener) {
|
public DownloadUtil(Context context, DownloadEntity entity, IDownloadListener downloadListener) {
|
||||||
this(context, entity, downloadListener, 3);
|
this(context, entity, downloadListener, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,7 +260,10 @@ final class DownloadUtil implements IDownloadUtil, Runnable {
|
|||||||
int fileLength = conn.getContentLength();
|
int fileLength = conn.getContentLength();
|
||||||
//必须建一个文件
|
//必须建一个文件
|
||||||
CommonUtil.createFile(mDownloadFile.getPath());
|
CommonUtil.createFile(mDownloadFile.getPath());
|
||||||
RandomAccessFile file = new RandomAccessFile(mDownloadFile.getPath(), "rwd");
|
//RandomAccessFile file = new RandomAccessFile(mDownloadFile.getPath(), "rwd");
|
||||||
|
////设置文件长度
|
||||||
|
//file.setLength(fileLength);
|
||||||
|
BufferedRandomAccessFile file = new BufferedRandomAccessFile(mDownloadFile.getPath(), "rwd", 8192);
|
||||||
//设置文件长度
|
//设置文件长度
|
||||||
file.setLength(fileLength);
|
file.setLength(fileLength);
|
||||||
mListener.onPostPre(fileLength);
|
mListener.onPostPre(fileLength);
|
||||||
|
@ -15,7 +15,11 @@
|
|||||||
*/
|
*/
|
||||||
package com.arialyy.aria.core.task;
|
package com.arialyy.aria.core.task;
|
||||||
|
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.os.Message;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import com.arialyy.aria.util.BufferedRandomAccessFile;
|
||||||
import com.arialyy.aria.util.CommonUtil;
|
import com.arialyy.aria.util.CommonUtil;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -33,7 +37,7 @@ import java.util.Properties;
|
|||||||
final class SingleThreadTask implements Runnable {
|
final class SingleThreadTask implements Runnable {
|
||||||
private static final String TAG = "SingleThreadTask";
|
private static final String TAG = "SingleThreadTask";
|
||||||
// TODO: 2017/2/22 不能使用1024 否则最大速度不能超过3m
|
// TODO: 2017/2/22 不能使用1024 否则最大速度不能超过3m
|
||||||
private static final int BUF_SIZE = 8196;
|
private static final int BUF_SIZE = 8192;
|
||||||
private DownloadUtil.ConfigEntity mConfigEntity;
|
private DownloadUtil.ConfigEntity mConfigEntity;
|
||||||
private String mConfigFPath;
|
private String mConfigFPath;
|
||||||
private long mChildCurrentLocation = 0;
|
private long mChildCurrentLocation = 0;
|
||||||
@ -77,9 +81,11 @@ final class SingleThreadTask implements Runnable {
|
|||||||
conn.setReadTimeout(mConstance.READ_TIME_OUT); //设置读取流的等待时间,必须设置该参数
|
conn.setReadTimeout(mConstance.READ_TIME_OUT); //设置读取流的等待时间,必须设置该参数
|
||||||
is = conn.getInputStream();
|
is = conn.getInputStream();
|
||||||
//创建可设置位置的文件
|
//创建可设置位置的文件
|
||||||
RandomAccessFile file = new RandomAccessFile(mConfigEntity.TEMP_FILE, "rwd");
|
BufferedRandomAccessFile
|
||||||
//设置每条线程写入文件的位置
|
file = new BufferedRandomAccessFile(mConfigEntity.TEMP_FILE, "rwd", 8192);
|
||||||
|
//设置文件长度
|
||||||
file.seek(mConfigEntity.START_LOCATION);
|
file.seek(mConfigEntity.START_LOCATION);
|
||||||
|
|
||||||
byte[] buffer = new byte[BUF_SIZE];
|
byte[] buffer = new byte[BUF_SIZE];
|
||||||
int len;
|
int len;
|
||||||
//当前子线程的下载位置
|
//当前子线程的下载位置
|
||||||
@ -175,12 +181,36 @@ final class SingleThreadTask implements Runnable {
|
|||||||
* 下载中
|
* 下载中
|
||||||
*/
|
*/
|
||||||
private void progress(long len) {
|
private void progress(long len) {
|
||||||
synchronized (LOCK) {
|
//synchronized (LOCK) {
|
||||||
mChildCurrentLocation += len;
|
mChildCurrentLocation += len;
|
||||||
mConstance.CURRENT_LOCATION += len;
|
mConstance.CURRENT_LOCATION += len;
|
||||||
|
//mListener.onProgress(mConstance.CURRENT_LOCATION);
|
||||||
|
//mHandler.post(t);
|
||||||
|
//handler.obtainMessage().sendToTarget();
|
||||||
|
//}
|
||||||
|
mHandler.sendEmptyMessage(1);
|
||||||
|
}
|
||||||
|
Handler mHandler = new Handler(Looper.getMainLooper()){
|
||||||
|
@Override public void handleMessage(Message msg) {
|
||||||
|
super.handleMessage(msg);
|
||||||
mListener.onProgress(mConstance.CURRENT_LOCATION);
|
mListener.onProgress(mConstance.CURRENT_LOCATION);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Thread t = new Thread(new Runnable() {
|
||||||
|
@Override public void run() {
|
||||||
|
mListener.onProgress(mConstance.CURRENT_LOCATION);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Handler handler = new Handler(){
|
||||||
|
// @Override public void handleMessage(Message msg) {
|
||||||
|
// super.handleMessage(msg);
|
||||||
|
// mListener.onProgress(mConstance.CURRENT_LOCATION);
|
||||||
|
// }
|
||||||
|
//};
|
||||||
|
|
||||||
|
Thread thread = new Thread();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 取消下载
|
* 取消下载
|
||||||
|
@ -0,0 +1,328 @@
|
|||||||
|
/**
|
||||||
|
* 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.*;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
@ -33,6 +33,8 @@ import butterknife.Bind;
|
|||||||
import com.arialyy.aria.core.AMTarget;
|
import com.arialyy.aria.core.AMTarget;
|
||||||
import com.arialyy.aria.core.Aria;
|
import com.arialyy.aria.core.Aria;
|
||||||
import com.arialyy.aria.core.DownloadEntity;
|
import com.arialyy.aria.core.DownloadEntity;
|
||||||
|
import com.arialyy.aria.core.task.DownloadUtil;
|
||||||
|
import com.arialyy.aria.core.task.IDownloadListener;
|
||||||
import com.arialyy.aria.core.task.Task;
|
import com.arialyy.aria.core.task.Task;
|
||||||
import com.arialyy.aria.util.CommonUtil;
|
import com.arialyy.aria.util.CommonUtil;
|
||||||
import com.arialyy.frame.util.show.L;
|
import com.arialyy.frame.util.show.L;
|
||||||
@ -198,6 +200,67 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
|
|||||||
.setDownloadPath(Environment.getExternalStorageDirectory().getPath() + "/test.apk")
|
.setDownloadPath(Environment.getExternalStorageDirectory().getPath() + "/test.apk")
|
||||||
.setDownloadName("test.apk")
|
.setDownloadName("test.apk")
|
||||||
.start();
|
.start();
|
||||||
|
//DownloadEntity entity = new DownloadEntity();
|
||||||
|
//entity.setDownloadUrl(DOWNLOAD_URL);
|
||||||
|
//entity.setDownloadPath(Environment.getExternalStorageDirectory().getPath() + "/test.apk");
|
||||||
|
//entity.setFileName("test.apk");
|
||||||
|
//DownloadUtil util = new DownloadUtil(this, entity, new IDownloadListener() {
|
||||||
|
// long fileSize = 1;
|
||||||
|
// @Override public void supportBreakpoint(boolean support) {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override public void onCancel() {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override public void onFail() {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override public void onPre() {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override public void onPostPre(long fileSize) {
|
||||||
|
// this.fileSize = fileSize;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override public void onProgress(long currentLocation) {
|
||||||
|
// long current = currentLocation;
|
||||||
|
// long len = fileSize;
|
||||||
|
// if (len == 0) {
|
||||||
|
// mPb.setProgress(0);
|
||||||
|
// } else {
|
||||||
|
// mPb.setProgress((int) ((current * 100) / len));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override public void onChildComplete(long finishLocation) {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override public void onStart(long startLocation) {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override public void onChildResume(long resumeLocation) {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override public void onResume(long resumeLocation) {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override public void onStop(long stopLocation) {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override public void onComplete() {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
//});
|
||||||
|
//util.startDownload();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void stop() {
|
private void stop() {
|
||||||
|
Reference in New Issue
Block a user