package ren.solid.library.http.subscriber;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.NonNull;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import io.reactivex.SingleObserver;
import io.reactivex.disposables.Disposable;
import okhttp3.ResponseBody;
import ren.solid.library.SolidApplication;
import ren.solid.library.utils.FileUtils;
/**
* Created by _SOLID
* Date:2016/8/1
* Time:16:40
*/
public abstract class DownLoadSubscribe implements SingleObserver<ResponseBody> {
private String mSaveFilePath;
private File mFile;
private Handler handler = new Handler(Looper.getMainLooper());
private long fileSizeDownloaded = 0;
private long fileSize = 0;
public DownLoadSubscribe(@NonNull String fileName) {
mSaveFilePath = FileUtils.getCacheDir(SolidApplication.getInstance()).getAbsolutePath();
mFile = new File(mSaveFilePath + File.separator + fileName);
}
public DownLoadSubscribe(@NonNull String filePath, @NonNull String fileName) {
mSaveFilePath = filePath;
mFile = new File(mSaveFilePath + File.separator + fileName);
}
@Override
public void onSubscribe(@io.reactivex.annotations.NonNull Disposable d) {
}
/**
* 下载进度回调
*
* @param progress 下载进度 0.0~1.0
* @param downloadByte 当前已经下载的字节
* @param totalByte 文件的总字节数
*/
public abstract void onProgress(double progress, long downloadByte, long totalByte);
/**
* 下载完成回调
*
* @param file 下载的文件
*/
public abstract void onCompleted(File file);
/**
* 下载失败的回调
*
* @param e error
*/
protected abstract void onFailed(Throwable e);
@Override
public final void onError(final Throwable e) {
handler.post(new Runnable() {
@Override
public void run() {
onFailed(e);
}
});
}
@Override
public final void onSuccess(@io.reactivex.annotations.NonNull ResponseBody responseBody) {
writeResponseBodyToDisk(responseBody);
handler.post(new Runnable() {
@Override
public void run() {
onCompleted(mFile);
}
});
}
public boolean writeResponseBodyToDisk(ResponseBody body) {
try {
InputStream inputStream = null;
OutputStream outputStream = null;
try {
byte[] fileReader = new byte[4096];
fileSize = body.contentLength();
inputStream = body.byteStream();
outputStream = new FileOutputStream(mFile);
while (true) {
int read = inputStream.read(fileReader);
if (read == -1) {
break;
}
outputStream.write(fileReader, 0, read);
fileSizeDownloaded += read;
handler.post(new Runnable() {
@Override
public void run() {
onProgress(fileSizeDownloaded * 1.0f / fileSize, fileSizeDownloaded, fileSize);
}
});
}
outputStream.flush();
return true;
} catch (final IOException e) {
handler.post(new Runnable() {
@Override
public void run() {
onError(e);
}
});
return false;
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
} catch (final IOException e) {
handler.post(new Runnable() {
@Override
public void run() {
onError(e);
}
});
return false;
}
}
}