public class OkHttpManager {
............省略..............
/**
* 异步(根据断点请求)
*
* @param url
* @param start
* @param end
* @param callback
* @return
*/
public Call initRequest(String url, long start, long end, final Callback callback) {
Request request = new Request.Builder()
.url(url)
.header("Range", "bytes=" + start + "-" + end)
.build();
Call call = builder.build().newCall(request);
call.enqueue(callback);
return call;
}
/**
* 同步请求
*
* @param url
* @return
* @throws IOException
*/
public Response initRequest(String url) throws IOException {
Request request = new Request.Builder()
.url(url)
.header("Range", "bytes=0-")
.build();
return builder.build().newCall(request).execute();
}
/**
* 文件存在的情况下可判断服务端文件是否已经更改
*
* @param url
* @param lastModify
* @return
* @throws IOException
*/
public Response initRequest(String url, String lastModify) throws IOException {
Request request = new Request.Builder()
.url(url)
.header("Range", "bytes=0-")
.header("If-Range", lastModify)
.build();
return builder.build().newCall(request).execute();
}
/**
* https请求时初始化证书
*
* @param certificates
* @return
*/
public void setCertificates(InputStream... certificates) {
try {
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null);
int index = 0;
for (InputStream certificate : certificates) {
String certificateAlias = Integer.toString(index++);
keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(certificate));
try {
if (certificate != null)
certificate.close();
} catch (IOException e) {
}
}
SSLContext sslContext = SSLContext.getInstance("TLS");
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());
builder.sslSocketFactory(sslContext.getSocketFactory());
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* download_info表建表语句
*/
public static final String CREATE_DOWNLOAD_INFO = "create table download_info ("
+ "id integer primary key autoincrement, "
+ "url text, "
+ "path text, "
+ "name text, "
+ "child_task_count integer, "
+ "current_length integer, "
+ "total_length integer, "
+ "percentage real, "
+ "last_modify text, "
+ "date text)";
public class ThreadPool {
//可同时下载的任务数(核心线程数)
private int CORE_POOL_SIZE = 3;
//缓存队列的大小(最大线程数)
private int MAX_POOL_SIZE = 20;
//非核心线程闲置的超时时间(秒),如果超时则会被回收
private long KEEP_ALIVE = 10L;
private ThreadPoolExecutor THREAD_POOL_EXECUTOR;
private ThreadFactory sThreadFactory = new ThreadFactory() {
private final AtomicInteger mCount = new AtomicInteger();
@Override
public Thread newThread(@NonNull Runnable runnable) {
return new Thread(runnable, "download_task#" + mCount.getAndIncrement());
}
};
...................省略................
public void setCorePoolSize(int corePoolSize) {
if (corePoolSize == 0) {
return;
}
CORE_POOL_SIZE = corePoolSize;
}
public void setMaxPoolSize(int maxPoolSize) {
if (maxPoolSize == 0) {
return;
}
MAX_POOL_SIZE = maxPoolSize;
}
public int getCorePoolSize() {
return CORE_POOL_SIZE;
}
public int getMaxPoolSize() {
return MAX_POOL_SIZE;
}
public ThreadPoolExecutor getThreadPoolExecutor() {
if (THREAD_POOL_EXECUTOR == null) {
THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(
CORE_POOL_SIZE, MAX_POOL_SIZE,
KEEP_ALIVE, TimeUnit.SECONDS,
new LinkedBlockingDeque<Runnable>(),
sThreadFactory);
}
return THREAD_POOL_EXECUTOR;
}
}
@Override
public void run() {
try {
File saveFile = new File(path, name);
File tempFile = new File(path, name + ".temp");
DownloadData data = Db.getInstance(context).getData(url);
if (Utils.isFileExists(saveFile) && Utils.isFileExists(tempFile) && data != null) {
Response response = OkHttpManager.getInstance().initRequest(url, data.getLastModify());
if (response != null && response.isSuccessful() && Utils.isNotServerFileChanged(response)) {
TEMP_FILE_TOTAL_SIZE = EACH_TEMP_SIZE * data.getChildTaskCount();
onStart(data.getTotalLength(), data.getCurrentLength(), "", true);
} else {
prepareRangeFile(response);
}
saveRangeFile();
} else {
Response response = OkHttpManager.getInstance().initRequest(url);
if (response != null && response.isSuccessful()) {
if (Utils.isSupportRange(response)) {
prepareRangeFile(response);
saveRangeFile();
} else {
saveCommonFile(response);
}
}
}
} catch (IOException e) {
onError(e.toString());
}
}
private void prepareRangeFile(Response response) {
.................省略.................
try {
File saveFile = Utils.createFile(path, name);
File tempFile = Utils.createFile(path, name + ".temp");
long fileLength = response.body().contentLength();
onStart(fileLength, 0, Utils.getLastModify(response), true);
Db.getInstance(context).deleteData(url);
Utils.deleteFile(saveFile, tempFile);
saveRandomAccessFile = new RandomAccessFile(saveFile, "rws");
saveRandomAccessFile.setLength(fileLength);
tempRandomAccessFile = new RandomAccessFile(tempFile, "rws");
tempRandomAccessFile.setLength(TEMP_FILE_TOTAL_SIZE);
tempChannel = tempRandomAccessFile.getChannel();
MappedByteBuffer buffer = tempChannel.map(READ_WRITE, 0, TEMP_FILE_TOTAL_SIZE);
long start;
long end;
int eachSize = (int) (fileLength / childTaskCount);
for (int i = 0; i < childTaskCount; i++) {
if (i == childTaskCount - 1) {
start = i * eachSize;
end = fileLength - 1;
} else {
start = i * eachSize;
end = (i + 1) * eachSize - 1;
}
buffer.putLong(start);
buffer.putLong(end);
}
} catch (Exception e) {
onError(e.toString());
} finally {
.............省略............
}
}
private void saveRangeFile() {
.................省略..............
for (int i = 0; i < childTaskCount; i++) {
final int tempI = i;
Call call = OkHttpManager.getInstance().initRequest(url, range.start[i], range.end[i], new Callback() {
@Override
public void onFailure(Call call, IOException e) {
onError(e.toString());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
startSaveRangeFile(response, tempI, range, saveFile, tempFile);
}
});
callList.add(call);
}
.................省略..............
}
private void startSaveRangeFile(Response response, int index, Ranges range, File saveFile, File tempFile) {
.................省略..............
try {
saveRandomAccessFile = new RandomAccessFile(saveFile, "rws");
saveChannel = saveRandomAccessFile.getChannel();
MappedByteBuffer saveBuffer = saveChannel.map(READ_WRITE, range.start[index], range.end[index] - range.start[index] + 1);
tempRandomAccessFile = new RandomAccessFile(tempFile, "rws");
tempChannel = tempRandomAccessFile.getChannel();
MappedByteBuffer tempBuffer = tempChannel.map(READ_WRITE, 0, TEMP_FILE_TOTAL_SIZE);
inputStream = response.body().byteStream();
int len;
byte[] buffer = new byte[BUFFER_SIZE];
while ((len = inputStream.read(buffer)) != -1) {
//取消
if (IS_CANCEL) {
handler.sendEmptyMessage(CANCEL);
callList.get(index).cancel();
break;
}
saveBuffer.put(buffer, 0, len);
tempBuffer.putLong(index * EACH_TEMP_SIZE, tempBuffer.getLong(index * EACH_TEMP_SIZE) + len);
onProgress(len);
//退出保存记录
if (IS_DESTROY) {
handler.sendEmptyMessage(DESTROY);
callList.get(index).cancel();
break;
}
//暂停
if (IS_PAUSE) {
handler.sendEmptyMessage(PAUSE);
callList.get(index).cancel();
break;
}
}
addCount();
} catch (Exception e) {
onError(e.toString());
} finally {
.................省略..............
}
saveBuffer.put(buffer, 0, len); tempBuffer.putLong(index * EACH_TEMP_SIZE, tempBuffer.getLong(index * EACH_TEMP_SIZE) + len);
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (mCurrentState) {
case START:
break;
case PROGRESS:
break;
case CANCEL:
break;
case PAUSE:
break;
case FINISH:
break;
case DESTROY:
break;
case ERROR:
break;
}
}
};
//如果正在下载的任务数量等于线程池的核心线程数,则新添加的任务处于等待状态
if (ThreadPool.getInstance().getThreadPoolExecutor().getActiveCount() == ThreadPool.getInstance().getCorePoolSize()) {
downloadCallback.onWait();
}
DUtil.init(mContext)
.url(url)
.path(Environment.getExternalStorageDirectory() + "/DUtil/")
.name(name.xxx)
.childTaskCount(3)
.build()
.start(callback);
new DownloadCallback() {
//开始
@Override
public void onStart(long currentSize, long totalSize, float progress) {
}
//下载中
@Override
public void onProgress(long currentSize, long totalSize, float progress) {
}
//暂停
@Override
public void onPause() {
}
//取消
@Override
public void onCancel() {
}
//下载完成
@Override
public void onFinish(File file) {
}
//等待
@Override
public void onWait() {
}
//下载出错
@Override
public void onError(String error) {
}
}
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有