refactor: replace RxDownload with my own implementation
This commit is contained in:
@@ -106,10 +106,6 @@ dependencies {
|
|||||||
// RxJava
|
// RxJava
|
||||||
compile "io.reactivex.rxjava2:rxjava:2.1.2"
|
compile "io.reactivex.rxjava2:rxjava:2.1.2"
|
||||||
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
|
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
|
||||||
// RxDownload
|
|
||||||
compile('zlc.season:rxdownload3:1.0.8', {
|
|
||||||
exclude group: 'com.android.support'
|
|
||||||
})
|
|
||||||
// Retrofit
|
// Retrofit
|
||||||
compile 'com.squareup.retrofit2:retrofit:2.3.0'
|
compile 'com.squareup.retrofit2:retrofit:2.3.0'
|
||||||
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
|
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.stardust.scriptdroid.network.api;
|
||||||
|
|
||||||
|
import io.reactivex.Observable;
|
||||||
|
import okhttp3.ResponseBody;
|
||||||
|
import retrofit2.http.GET;
|
||||||
|
import retrofit2.http.Streaming;
|
||||||
|
import retrofit2.http.Url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Stardust on 2017/12/6.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface DownloadApi {
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Streaming
|
||||||
|
Observable<ResponseBody> download(@Url String url);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,17 +1,24 @@
|
|||||||
package com.stardust.scriptdroid.network.download;
|
package com.stardust.scriptdroid.network.download;
|
||||||
|
|
||||||
import android.content.Context;
|
import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
|
||||||
|
import com.stardust.concurrent.VolatileBox;
|
||||||
|
import com.stardust.scriptdroid.network.NodeBB;
|
||||||
|
import com.stardust.scriptdroid.network.api.DownloadApi;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.net.URLDecoder;
|
import java.net.URLDecoder;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import io.reactivex.Observable;
|
import io.reactivex.Observable;
|
||||||
|
import io.reactivex.schedulers.Schedulers;
|
||||||
import io.reactivex.subjects.PublishSubject;
|
import io.reactivex.subjects.PublishSubject;
|
||||||
import retrofit2.http.Url;
|
import okhttp3.OkHttpClient;
|
||||||
import zlc.season.rxdownload3.RxDownload;
|
import okhttp3.Request;
|
||||||
import zlc.season.rxdownload3.core.Failed;
|
import okhttp3.Response;
|
||||||
import zlc.season.rxdownload3.core.Mission;
|
import okhttp3.ResponseBody;
|
||||||
import zlc.season.rxdownload3.core.Succeed;
|
import retrofit2.Retrofit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Stardust on 2017/10/20.
|
* Created by Stardust on 2017/10/20.
|
||||||
@@ -21,16 +28,36 @@ public class DownloadManager {
|
|||||||
|
|
||||||
private static DownloadManager sInstance;
|
private static DownloadManager sInstance;
|
||||||
|
|
||||||
private Context mContext;
|
private static final int RETRY_COUNT = 3;
|
||||||
|
private Retrofit mRetrofit;
|
||||||
|
private DownloadApi mDownloadApi;
|
||||||
|
private ConcurrentHashMap<String, VolatileBox<Boolean>> mDownloadStatuses = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
public DownloadManager() {
|
||||||
public DownloadManager(Context context) {
|
mRetrofit = new Retrofit.Builder()
|
||||||
mContext = context;
|
.baseUrl(NodeBB.BASE_URL)
|
||||||
|
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
|
||||||
|
.client(new OkHttpClient.Builder()
|
||||||
|
.addInterceptor(chain -> {
|
||||||
|
Request request = chain.request();
|
||||||
|
Response response = chain.proceed(request);
|
||||||
|
int tryCount = 0;
|
||||||
|
while (!response.isSuccessful() && tryCount < RETRY_COUNT) {
|
||||||
|
tryCount++;
|
||||||
|
response = chain.proceed(request);
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.build();
|
||||||
|
mDownloadApi = mRetrofit.create(DownloadApi.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DownloadManager getInstance(Context context) {
|
|
||||||
|
public static DownloadManager getInstance() {
|
||||||
if (sInstance == null) {
|
if (sInstance == null) {
|
||||||
sInstance = new DownloadManager(context);
|
sInstance = new DownloadManager();
|
||||||
}
|
}
|
||||||
return sInstance;
|
return sInstance;
|
||||||
}
|
}
|
||||||
@@ -45,28 +72,89 @@ public class DownloadManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Observable<Integer> download(String url, String path) {
|
public Observable<Integer> download(String url, String path) {
|
||||||
File file = new File(path);
|
DownloadTask task = new DownloadTask(url, path);
|
||||||
Mission mission = new Mission(url, file.getName(), file.getParent());
|
mDownloadApi.download(url)
|
||||||
PublishSubject<Integer> progress = PublishSubject.create();
|
.subscribeOn(Schedulers.io())
|
||||||
RxDownload.INSTANCE.create(mission)
|
.subscribe(task::start);
|
||||||
.subscribe(status -> {
|
return task.progress();
|
||||||
if (status.getTotalSize() > 0) {
|
|
||||||
int p = (int) Math.floor((float) status.getDownloadSize() / status.getTotalSize() * 100);
|
|
||||||
progress.onNext(p);
|
|
||||||
}
|
|
||||||
if (status instanceof Succeed) {
|
|
||||||
progress.onComplete();
|
|
||||||
RxDownload.INSTANCE.delete(mission);
|
|
||||||
} else if (status instanceof Failed) {
|
|
||||||
progress.onError(((Failed) status).getThrowable());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
RxDownload.INSTANCE.start(mission).subscribe();
|
|
||||||
return progress;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cancelDownload(String url) {
|
public void cancelDownload(String url) {
|
||||||
RxDownload.INSTANCE.stop(url);
|
VolatileBox<Boolean> status = mDownloadStatuses.get(url);
|
||||||
RxDownload.INSTANCE.delete(url);
|
if (status != null) {
|
||||||
|
status.set(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class DownloadTask {
|
||||||
|
|
||||||
|
private String mUrl;
|
||||||
|
private String mPath;
|
||||||
|
private VolatileBox<Boolean> mStatus;
|
||||||
|
private InputStream mInputStream;
|
||||||
|
private FileOutputStream mFileOutputStream;
|
||||||
|
private PublishSubject<Integer> mProgress;
|
||||||
|
|
||||||
|
public DownloadTask(String url, String path) {
|
||||||
|
mUrl = url;
|
||||||
|
mPath = path;
|
||||||
|
mStatus = new VolatileBox<>(true);
|
||||||
|
VolatileBox<Boolean> previous = mDownloadStatuses.put(mUrl, mStatus);
|
||||||
|
if (previous != null)
|
||||||
|
previous.set(false);
|
||||||
|
mProgress = PublishSubject.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start(ResponseBody body) throws IOException {
|
||||||
|
byte[] buffer = new byte[4096];
|
||||||
|
mFileOutputStream = new FileOutputStream(mPath);
|
||||||
|
mInputStream = body.byteStream();
|
||||||
|
long total = body.contentLength();
|
||||||
|
long read = 0;
|
||||||
|
while (read < total) {
|
||||||
|
if (!mStatus.get()) {
|
||||||
|
onCancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int len = mInputStream.read(buffer);
|
||||||
|
if (len == -1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
read += len;
|
||||||
|
mFileOutputStream.write(buffer, 0, len);
|
||||||
|
mProgress.onNext((int) (100 * read / total));
|
||||||
|
}
|
||||||
|
mProgress.onComplete();
|
||||||
|
recycle();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onCancel() throws IOException {
|
||||||
|
recycle();
|
||||||
|
// TODO: 2017/12/6 notify?
|
||||||
|
}
|
||||||
|
|
||||||
|
public void recycle() {
|
||||||
|
mDownloadStatuses.remove(mUrl);
|
||||||
|
if (mInputStream != null) {
|
||||||
|
try {
|
||||||
|
mInputStream.close();
|
||||||
|
} catch (IOException ignored) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mFileOutputStream != null) {
|
||||||
|
try {
|
||||||
|
mFileOutputStream.close();
|
||||||
|
} catch (IOException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Observable<Integer> progress() {
|
||||||
|
return mProgress;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -265,13 +265,13 @@ public class ScriptOperations {
|
|||||||
.title(fileName)
|
.title(fileName)
|
||||||
.cancelable(false)
|
.cancelable(false)
|
||||||
.positiveText(R.string.text_cancel_download)
|
.positiveText(R.string.text_cancel_download)
|
||||||
.onPositive((dialog, which) -> DownloadManager.getInstance(mContext).cancelDownload(url))
|
.onPositive((dialog, which) -> DownloadManager.getInstance().cancelDownload(url))
|
||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Observable<ScriptFile> download(String url, String path, MaterialDialog progressDialog) {
|
public Observable<ScriptFile> download(String url, String path, MaterialDialog progressDialog) {
|
||||||
PublishSubject<ScriptFile> subject = PublishSubject.create();
|
PublishSubject<ScriptFile> subject = PublishSubject.create();
|
||||||
DownloadManager.getInstance(mContext).download(url, path)
|
DownloadManager.getInstance().download(url, path)
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.doOnNext(progressDialog::setProgress)
|
.doOnNext(progressDialog::setProgress)
|
||||||
.doOnComplete(() -> {
|
.doOnComplete(() -> {
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import com.stardust.scriptdroid.Pref;
|
|||||||
import com.stardust.scriptdroid.R;
|
import com.stardust.scriptdroid.R;
|
||||||
import com.stardust.scriptdroid.autojs.AutoJs;
|
import com.stardust.scriptdroid.autojs.AutoJs;
|
||||||
import com.stardust.scriptdroid.ui.common.NotAskAgainDialog;
|
import com.stardust.scriptdroid.ui.common.NotAskAgainDialog;
|
||||||
|
import com.stardust.scriptdroid.ui.common.ScriptOperations;
|
||||||
import com.stardust.scriptdroid.ui.doc.DocsFragment_;
|
import com.stardust.scriptdroid.ui.doc.DocsFragment_;
|
||||||
import com.stardust.scriptdroid.ui.floating.FloatyWindowManger;
|
import com.stardust.scriptdroid.ui.floating.FloatyWindowManger;
|
||||||
import com.stardust.scriptdroid.storage.file.StorageFileProvider;
|
import com.stardust.scriptdroid.storage.file.StorageFileProvider;
|
||||||
|
|||||||
Reference in New Issue
Block a user