10 Commits

Author SHA1 Message Date
lyy
aa292e4389 Merge pull request #914 from wangkai9799/master
网络切换导致下载失败
2021-09-05 12:30:26 +08:00
lyy
cba9483f3a Merge pull request #918 from bihailantian/patch-1
Update SFtpURecordHandler.java(fix SFTP断点续传上传文件错误)
2021-09-05 12:29:41 +08:00
bihailantian
eeb0bea97a Update SFtpURecordHandler.java
fix SFTP断点上传文件错误
2021-09-02 16:32:27 +08:00
wangkai
3fc99cd01e 网络切换导致下载失败 2021-08-31 13:18:20 +08:00
lyy
48af5509f5 Merge pull request #910 from ls1110924/master
fix: 修复Entity使用Parcel序列化时丢失rowId的问题
2021-08-25 20:28:08 +08:00
A Shuai
56893b0d88 fix: 修复Entity使用Parcel序列化时丢失rowId的问题 2021-08-17 23:54:02 +08:00
lyy
ada1f9f993 Merge pull request #907 from Equalzys/3.8.16.1
修改3个bug #886、#897、#899
2021-08-16 15:29:00 +08:00
Equalzys
7392eba667 1、修改上传文件时去合并文件的错误
2、捕获sql查询失败异常
3、修复下载文件获取不到文件长度而导致合并失败的问题
2021-08-12 13:36:13 +08:00
lyy
3e2c3bc055 Update stale.yml 2021-07-06 10:40:37 +08:00
lyy
6e9f674fab Update README.md 2021-04-20 09:42:30 +08:00
12 changed files with 881 additions and 577 deletions

2
.github/stale.yml vendored
View File

@@ -1,7 +1,7 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 7
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 100
daysUntilClose: 1000
# Issues with these labels will never be considered stale
exemptLabels:
- bug

View File

@@ -23,6 +23,7 @@ import com.arialyy.aria.core.loader.AbsNormalTTBuilderAdapter;
import com.arialyy.aria.core.loader.LoaderStructure;
import com.arialyy.aria.core.loader.NormalTTBuilder;
import com.arialyy.aria.core.loader.NormalThreadStateManager;
import com.arialyy.aria.core.loader.UploadThreadStateManager;
import com.arialyy.aria.core.task.IThreadTaskAdapter;
import com.arialyy.aria.core.upload.UTaskWrapper;
import com.arialyy.aria.ftp.FtpTaskOption;
@@ -44,7 +45,8 @@ public final class FtpULoaderUtil extends AbsNormalLoaderUtil {
@Override public LoaderStructure BuildLoaderStructure() {
LoaderStructure structure = new LoaderStructure();
structure.addComponent(new FtpURecordHandler((UTaskWrapper) getTaskWrapper()))
.addComponent(new NormalThreadStateManager(getListener()))
// .addComponent(new NormalThreadStateManager(getListener()))
.addComponent(new UploadThreadStateManager(getListener()))
.addComponent(new FtpUFileInfoTask((UTaskWrapper) getTaskWrapper()))
.addComponent(new NormalTTBuilder(getTaskWrapper(), new AbsNormalTTBuilderAdapter() {
@Override public IThreadTaskAdapter getAdapter(SubThreadConfig config) {

View File

@@ -23,6 +23,7 @@ import com.arialyy.aria.core.loader.AbsNormalTTBuilderAdapter;
import com.arialyy.aria.core.loader.LoaderStructure;
import com.arialyy.aria.core.loader.NormalTTBuilder;
import com.arialyy.aria.core.loader.NormalThreadStateManager;
import com.arialyy.aria.core.loader.UploadThreadStateManager;
import com.arialyy.aria.core.task.IThreadTaskAdapter;
import com.arialyy.aria.core.upload.UTaskWrapper;
import com.arialyy.aria.http.HttpRecordHandler;
@@ -45,7 +46,8 @@ public final class HttpULoaderUtil extends AbsNormalLoaderUtil {
@Override public LoaderStructure BuildLoaderStructure() {
LoaderStructure structure = new LoaderStructure();
structure.addComponent(new HttpRecordHandler(getTaskWrapper()))
.addComponent(new NormalThreadStateManager(getListener()))
// .addComponent(new NormalThreadStateManager(getListener()))
.addComponent(new UploadThreadStateManager(getListener()))
.addComponent(new NormalTTBuilder(getTaskWrapper(), new AbsNormalTTBuilderAdapter() {
@Override public IThreadTaskAdapter getAdapter(SubThreadConfig config) {
return new HttpUThreadTaskAdapter(config);

View File

@@ -157,7 +157,7 @@ public class AriaConfig {
}
}
private boolean isNetworkAvailable() {
public boolean isNetworkAvailable() {
// 获取手机所有连接管理对象包括对wi-fi,net等连接的管理
ConnectivityManager connectivityManager =
(ConnectivityManager) getAPP().getSystemService(Context.CONNECTIVITY_SERVICE);

View File

@@ -234,6 +234,7 @@ public abstract class AbsEntity extends DbEntity implements IEntity, Parcelable,
}
@Override public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(this.rowID);
dest.writeLong(this.speed);
dest.writeString(this.convertSpeed);
dest.writeInt(this.failNum);
@@ -249,6 +250,7 @@ public abstract class AbsEntity extends DbEntity implements IEntity, Parcelable,
}
protected AbsEntity(Parcel in) {
this.rowID = in.readLong();
this.speed = in.readLong();
this.convertSpeed = in.readString();
this.failNum = in.readInt();

View File

@@ -249,8 +249,14 @@ public class NormalThreadStateManager implements IThreadStateManager {
private boolean mergeFile() {
if (mTaskRecord.threadNum == 1) {
File targetFile = new File(mTaskRecord.filePath);
if (targetFile.exists() && targetFile.length() == mTaskRecord.fileLength){
return true;
if (targetFile.exists()){
//没有获得文件长度:不支持断点续传
if (mTaskRecord.fileLength == 0 && targetFile.length() != 0) {
return true;
}
if (targetFile.length() != 0 && targetFile.length() == mTaskRecord.fileLength) {
return true;
}
}
FileUtil.deleteFile(targetFile);
File partFile = new File(String.format(IRecordHandler.SUB_PATH, mTaskRecord.filePath, 0));

View File

@@ -0,0 +1,275 @@
/*
* 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.loader;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import com.arialyy.aria.core.TaskRecord;
import com.arialyy.aria.core.inf.IThreadStateManager;
import com.arialyy.aria.core.listener.IEventListener;
import com.arialyy.aria.exception.AriaException;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.aria.util.FileUtil;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 线程任务管理器,用于处理多线程下载时任务的状态回调
*/
public class UploadThreadStateManager implements IThreadStateManager {
private final String TAG = CommonUtil.getClassName(this);
/**
* 任务状态回调
*/
private IEventListener mListener;
private int mThreadNum; // 启动的线程总数
private AtomicInteger mCancelNum = new AtomicInteger(0); // 已经取消的线程的数
private AtomicInteger mStopNum = new AtomicInteger(0); // 已经停止的线程数
private AtomicInteger mFailNum = new AtomicInteger(0); // 失败的线程数
private AtomicInteger mCompleteNum = new AtomicInteger(0); // 完成的线程数
private long mProgress; //当前总进度
private TaskRecord mTaskRecord; // 任务记录
private Looper mLooper;
/**
* @param listener 任务事件
*/
public UploadThreadStateManager(IEventListener listener) {
mListener = listener;
}
@Override public void setLooper(TaskRecord taskRecord, Looper looper) {
mTaskRecord = taskRecord;
mThreadNum = mTaskRecord.threadNum;
mLooper = looper;
}
private void checkLooper() {
if (mTaskRecord == null) {
throw new NullPointerException("任务记录为空");
}
if (mLooper == null) {
throw new NullPointerException("Looper为空");
}
}
private Handler.Callback callback = new Handler.Callback() {
@Override public boolean handleMessage(Message msg) {
checkLooper();
switch (msg.what) {
case STATE_STOP:
mStopNum.getAndIncrement();
if (isStop()) {
quitLooper();
}
break;
case STATE_CANCEL:
mCancelNum.getAndIncrement();
if (isCancel()) {
quitLooper();
}
break;
case STATE_FAIL:
mFailNum.getAndIncrement();
if (isFail()) {
Bundle b = msg.getData();
mListener.onFail(b.getBoolean(DATA_RETRY, false),
(AriaException) b.getSerializable(DATA_ERROR_INFO));
quitLooper();
}
break;
case STATE_COMPLETE:
mCompleteNum.getAndIncrement();
if (isComplete()) {
ALog.d(TAG, "isComplete, completeNum = " + mCompleteNum);
//上传文件不需要合并文件
mListener.onComplete();
quitLooper();
}
break;
case STATE_RUNNING:
Bundle b = msg.getData();
if (b != null) {
long len = b.getLong(IThreadStateManager.DATA_ADD_LEN, 0);
mProgress += len;
}
break;
case STATE_UPDATE_PROGRESS:
if (msg.obj == null) {
mProgress = updateBlockProgress();
} else if (msg.obj instanceof Long) {
mProgress = (long) msg.obj;
}
break;
}
return false;
}
};
@Override public void updateCurrentProgress(long currentProgress) {
mProgress = currentProgress;
}
/**
* 退出looper循环
*/
private void quitLooper() {
mLooper.quit();
}
/**
* 获取当前任务下载进度
*
* @return 当前任务下载进度
*/
@Override
public long getCurrentProgress() {
return mProgress;
}
@Override public Handler.Callback getHandlerCallback() {
return callback;
}
/**
* 所有子线程是否都已经停止
*/
public boolean isStop() {
//ALog.d(TAG,
// String.format("isStop; stopNum: %s, cancelNum: %s, failNum: %s, completeNum: %s", mStopNum,
// mCancelNum, mFailNum, mCompleteNum));
return mStopNum.get() == mThreadNum || mStopNum.get() + mCompleteNum.get() == mThreadNum;
}
/**
* 所有子线程是否都已经失败
*/
@Override
public boolean isFail() {
//ALog.d(TAG,
// String.format("isFail; stopNum: %s, cancelNum: %s, failNum: %s, completeNum: %s", mStopNum,
// mCancelNum, mFailNum, mCompleteNum));
return mCompleteNum.get() != mThreadNum
&& (mFailNum.get() == mThreadNum || mFailNum.get() + mCompleteNum.get() == mThreadNum);
}
/**
* 所有子线程是否都已经完成
*/
@Override
public boolean isComplete() {
//ALog.d(TAG,
// String.format("isComplete; stopNum: %s, cancelNum: %s, failNum: %s, completeNum: %s",
// mStopNum,
// mCancelNum, mFailNum, mCompleteNum));
return mCompleteNum.get() == mThreadNum;
}
/**
* 所有子线程是否都已经取消
*/
public boolean isCancel() {
//ALog.d(TAG, String.format("isCancel; stopNum: %s, cancelNum: %s, failNum: %s, completeNum: %s",
// mStopNum,
// mCancelNum, mFailNum, mCompleteNum));
return mCancelNum.get() == mThreadNum;
}
/**
* 更新分块任务s的真实进度
*/
private long updateBlockProgress() {
long size = 0;
for (int i = 0, len = mTaskRecord.threadRecords.size(); i < len; i++) {
File temp = new File(String.format(IRecordHandler.SUB_PATH, mTaskRecord.filePath, i));
if (temp.exists()) {
size += temp.length();
}
}
return size;
}
/**
* 合并sftp的分块
*/
private boolean mergerSFtp() {
if (mTaskRecord.threadNum == 1) {
File partFile = new File(String.format(IRecordHandler.SUB_PATH, mTaskRecord.filePath, 0));
return partFile.renameTo(new File(mTaskRecord.filePath));
}
List<String> partPath = new ArrayList<>();
for (int i = 0, len = mTaskRecord.threadNum; i < len; i++) {
partPath.add(String.format(IRecordHandler.SUB_PATH, mTaskRecord.filePath, i));
}
FileUtil.mergeSFtpFile(mTaskRecord.filePath, partPath, mTaskRecord.fileLength);
for (String pp : partPath) {
FileUtil.deleteFile(pp);
}
return true;
}
/**
* 合并文件
*
* @return {@code true} 合并成功,{@code false}合并失败
*/
private boolean mergeFile() {
if (mTaskRecord.threadNum == 1) {
File targetFile = new File(mTaskRecord.filePath);
if (targetFile.exists() && targetFile.length() == mTaskRecord.fileLength){
return true;
}
FileUtil.deleteFile(targetFile);
File partFile = new File(String.format(IRecordHandler.SUB_PATH, mTaskRecord.filePath, 0));
return partFile.renameTo(targetFile);
}
List<String> partPath = new ArrayList<>();
for (int i = 0, len = mTaskRecord.threadNum; i < len; i++) {
partPath.add(String.format(IRecordHandler.SUB_PATH, mTaskRecord.filePath, i));
}
boolean isSuccess = FileUtil.mergeFile(mTaskRecord.filePath, partPath);
if (isSuccess) {
for (String pp : partPath) {
FileUtil.deleteFile(pp);
}
File targetFile = new File(mTaskRecord.filePath);
if (targetFile.exists() && targetFile.length() > mTaskRecord.fileLength) {
ALog.e(TAG, String.format("任务【%s】分块文件合并失败下载长度超出文件真实长度downloadLen: %sfileSize: %s",
targetFile.getName(), targetFile.length(), mTaskRecord.fileLength));
return false;
}
return true;
} else {
ALog.e(TAG, "合并失败");
return false;
}
}
@Override public void accept(ILoaderVisitor visitor) {
visitor.addComponent(this);
}
}

View File

@@ -61,7 +61,7 @@ public class NetUtils {
return true;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
return AriaConfig.getInstance().isConnectedNet();
return AriaConfig.getInstance().isNetworkAvailable();
}
ConnectivityManager cm =
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

View File

@@ -53,11 +53,19 @@ Aria有以下特点
```java
implementation 'me.laoyuyu.aria:core:3.8.16'
annotationProcessor 'me.laoyuyu.aria:compiler:3.8.16'
implementation 'me.laoyuyu.aria:ftp:3.8.16' # 如果需要使用ftp请增加该组件
implementation 'me.laoyuyu.aria:sftp:3.8.16' # 如果需要使用ftp请增加该组件
implementation 'me.laoyuyu.aria:m3u8:3.8.16' # 如果需要使用m3u8下载功能请增加该组件
repositories {
google()
mavenCentral()
}
dependencies {
implementation 'me.laoyuyu.aria:core:3.8.16'
annotationProcessor 'me.laoyuyu.aria:compiler:3.8.16'
implementation 'me.laoyuyu.aria:ftp:3.8.16' # 如果需要使用ftp请增加该组件
implementation 'me.laoyuyu.aria:sftp:3.8.16' # 如果需要使用ftp请增加该组件
implementation 'me.laoyuyu.aria:m3u8:3.8.16' # 如果需要使用m3u8下载功能请增加该组件
}
```
如果你使用的是kotlin请使用kotlin官方提供的方法配置apt[kotlin kapt官方配置传送门](https://www.kotlincn.net/docs/reference/kapt.html)

View File

@@ -20,6 +20,7 @@ import com.arialyy.aria.core.loader.AbsNormalLoaderUtil;
import com.arialyy.aria.core.loader.LoaderStructure;
import com.arialyy.aria.core.loader.NormalTTBuilder;
import com.arialyy.aria.core.loader.NormalThreadStateManager;
import com.arialyy.aria.core.loader.UploadThreadStateManager;
import com.arialyy.aria.core.upload.UTaskWrapper;
import com.arialyy.aria.sftp.SFtpTaskOption;
@@ -41,7 +42,8 @@ public class SFtpULoaderUtil extends AbsNormalLoaderUtil {
@Override public LoaderStructure BuildLoaderStructure() {
LoaderStructure structure = new LoaderStructure();
structure.addComponent(new SFtpURecordHandler((UTaskWrapper) getTaskWrapper()))
.addComponent(new NormalThreadStateManager(getListener()))
// .addComponent(new NormalThreadStateManager(getListener()))
.addComponent(new UploadThreadStateManager(getListener()))
.addComponent(new SFtpUInfoTask((UTaskWrapper) getTaskWrapper()))
.addComponent(new NormalTTBuilder(getTaskWrapper(), new SFtpUTTBuilderAdapter(
(UTaskWrapper) getTaskWrapper())));

View File

@@ -63,14 +63,14 @@ final class SFtpURecordHandler extends RecordHandler {
+ ftpAttrs.getSize()
+ ""
+ "尝试从位置:"
+ (ftpAttrs.getSize() - 1)
+ ftpAttrs.getSize()
+ "开始上传");
getWrapper().setNewTask(false);
// 修改记录
ThreadRecord threadRecord = record.threadRecords.get(0);
//修改本地保存的停止地址为服务器上对应文件的大小
threadRecord.startLocation = ftpAttrs.getSize() - 1;
threadRecord.startLocation = ftpAttrs.getSize();
}
} else {
ALog.d(TAG, "SFTP服务器上不存在该文件");