Commit b5200563 by pye52

文件下载操作由第三方库filedownloader完成

parent 6c38c763
...@@ -118,4 +118,5 @@ dependencies { ...@@ -118,4 +118,5 @@ dependencies {
def lifecycle_version = "2.2.0" def lifecycle_version = "2.2.0"
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version" implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version" implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
implementation 'com.liulishuo.filedownloader:library:1.7.7'
} }
package com.bgycc.smartcanteen.command; package com.bgycc.smartcanteen.command;
import com.bgycc.smartcanteen.BuildConfig; import com.bgycc.smartcanteen.BuildConfig;
import com.bgycc.smartcanteen.api.SCRetrofit;
import com.bgycc.smartcanteen.entity.Command; import com.bgycc.smartcanteen.entity.Command;
import com.bgycc.smartcanteen.entity.CommandResponse; import com.bgycc.smartcanteen.entity.CommandResponse;
import com.bgycc.smartcanteen.entity.CommandUpdate; import com.bgycc.smartcanteen.entity.CommandUpdate;
import com.bgycc.smartcanteen.entity.ProgressResponseBody;
import com.bgycc.smartcanteen.utils.DeviceProxy; import com.bgycc.smartcanteen.utils.DeviceProxy;
import com.blankj.utilcode.util.AppUtils; import com.blankj.utilcode.util.AppUtils;
import com.blankj.utilcode.util.FileIOUtils;
import com.blankj.utilcode.util.FileUtils; import com.blankj.utilcode.util.FileUtils;
import com.blankj.utilcode.util.LogUtils; import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.PathUtils; import com.blankj.utilcode.util.PathUtils;
import com.blankj.utilcode.util.Utils;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.liulishuo.filedownloader.BaseDownloadTask;
import org.jetbrains.annotations.NotNull; import com.liulishuo.filedownloader.FileDownloadListener;
import com.liulishuo.filedownloader.FileDownloadSampleListener;
import com.liulishuo.filedownloader.FileDownloader;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import static com.bgycc.smartcanteen.utils.SmartCanteenUtils.TAG; import static com.bgycc.smartcanteen.utils.SmartCanteenUtils.TAG;
/** /**
...@@ -38,18 +25,12 @@ import static com.bgycc.smartcanteen.utils.SmartCanteenUtils.TAG; ...@@ -38,18 +25,12 @@ import static com.bgycc.smartcanteen.utils.SmartCanteenUtils.TAG;
*/ */
public class UpdateCommandHandler extends CommandHandler { public class UpdateCommandHandler extends CommandHandler {
private static final String UPDATE_APK = "SmartCanteen-update.apk"; private static final String UPDATE_APK = "SmartCanteen-update.apk";
// 下载超时为60s private static final String UPDATE_APK_PATH = PathUtils.getExternalStoragePath() + File.separator + UPDATE_APK;
private static final long TIMEOUT = 60 * 1000;
private static final long DEFAULT_DELAY = 5 * 1000; private static final long DEFAULT_DELAY = 5 * 1000;
// 保证更新任务不会在同一时间内重复执行
private volatile boolean start = false; private volatile boolean start = false;
private OkHttpClient httpClient;
private CommandUpdate commandUpdate; private CommandUpdate commandUpdate;
private File updateApk;
// 避免下载异常,这里创建自己的线程池(毕竟收到更新通知时一般都会进入安装流程,无需担心开销)
private ScheduledExecutorService executor;
private ScheduledFuture<?> timeoutFuture;
private static UpdateCommandHandler instance; private static UpdateCommandHandler instance;
...@@ -66,20 +47,7 @@ public class UpdateCommandHandler extends CommandHandler { ...@@ -66,20 +47,7 @@ public class UpdateCommandHandler extends CommandHandler {
private UpdateCommandHandler(Command command, Gson gson, CommandProgressCallback callback) { private UpdateCommandHandler(Command command, Gson gson, CommandProgressCallback callback) {
super(command, gson, callback); super(command, gson, callback);
this.httpClient = SCRetrofit.createUnsafeOkHttpClientBuilder()
.addNetworkInterceptor(chain -> {
Response originalResponse = chain.proceed(chain.request());
return originalResponse.newBuilder()
.body(new ProgressResponseBody(originalResponse.body(), (progress, total, done) -> {
int per = (int) (progress * 1f / total * 100);
wait("下载进度: " + per + "%", per);
}))
.build();
})
.build();
this.commandUpdate = gson.fromJson(command.getData(), CommandUpdate.class); this.commandUpdate = gson.fromJson(command.getData(), CommandUpdate.class);
this.updateApk = new File(PathUtils.getExternalStoragePath(), UPDATE_APK);
FileUtils.delete(updateApk);
} }
private void init(Command command, Gson gson, CommandProgressCallback callback) { private void init(Command command, Gson gson, CommandProgressCallback callback) {
...@@ -87,7 +55,6 @@ public class UpdateCommandHandler extends CommandHandler { ...@@ -87,7 +55,6 @@ public class UpdateCommandHandler extends CommandHandler {
this.gson = gson; this.gson = gson;
this.commandProgressCallback = callback; this.commandProgressCallback = callback;
this.commandUpdate = gson.fromJson(command.getData(), CommandUpdate.class); this.commandUpdate = gson.fromJson(command.getData(), CommandUpdate.class);
this.updateApk = new File(PathUtils.getExternalStoragePath(), UPDATE_APK);
} }
@Override @Override
...@@ -97,37 +64,38 @@ public class UpdateCommandHandler extends CommandHandler { ...@@ -97,37 +64,38 @@ public class UpdateCommandHandler extends CommandHandler {
return null; return null;
} }
start = true; start = true;
FileUtils.delete(updateApk);
if (executor == null) {
executor = Executors.newScheduledThreadPool(1);
}
if (commandUpdate.getData() == null || commandUpdate.getData().getUrl() == null) { if (commandUpdate.getData() == null || commandUpdate.getData().getUrl() == null) {
LogUtils.d(TAG, "更新包地址异常: " + commandUpdate.toString()); LogUtils.d(TAG, "更新包地址异常: " + commandUpdate.toString());
return failedResult("更新包地址异常"); return failedResult("更新包地址异常");
} }
String url = commandUpdate.getData().getUrl(); String url = commandUpdate.getData().getUrl();
Request request = new Request.Builder() FileDownloader.setup(Utils.getApp());
.url(url) FileDownloader.getImpl()
.build(); .create(url)
LogUtils.d(TAG, "更新包开始下载: " + url); .setPath(UPDATE_APK_PATH)
wait("开始下载", 0); .setAutoRetryTimes(3)
timeoutFuture = executor.schedule(timeoutRunnable, TIMEOUT, TimeUnit.MILLISECONDS); .setSyncCallback(true)
httpClient.newCall(request).enqueue(callback); .setForceReDownload(true)
.setListener(listener)
.start();
return successResult("开始下载"); return successResult("开始下载");
} }
private Runnable timeoutRunnable = () -> { private FileDownloadListener listener = new FileDownloadSampleListener() {
LogUtils.w(TAG, "安装包下载超时"); @Override
start = false; protected void started(BaseDownloadTask task) {
}; LogUtils.d(TAG, "更新包开始下载: " + task.getUrl());
UpdateCommandHandler.this.wait("开始下载", 0);
}
private Callback callback = new Callback() {
@Override @Override
public void onFailure(@NotNull Call call, @NotNull IOException e) { protected void progress(BaseDownloadTask task, int soFarBytes, int totalBytes) {
if (timeoutFuture != null) { int per = (int) (soFarBytes * 1f / totalBytes * 100);
timeoutFuture.cancel(true); UpdateCommandHandler.this.wait("下载进度: " + per + "%", per);
timeoutFuture = null;
} }
@Override
protected void error(BaseDownloadTask task, Throwable e) {
LogUtils.e(TAG, "下载失败: " + e.getMessage(), e); LogUtils.e(TAG, "下载失败: " + e.getMessage(), e);
failed("下载失败", 0); failed("下载失败", 0);
try { try {
...@@ -140,21 +108,10 @@ public class UpdateCommandHandler extends CommandHandler { ...@@ -140,21 +108,10 @@ public class UpdateCommandHandler extends CommandHandler {
} }
@Override @Override
public void onResponse(@NotNull Call call, @NotNull Response response) { protected void completed(BaseDownloadTask task) {
if (timeoutFuture != null) { File updateApk = new File(UPDATE_APK_PATH);
timeoutFuture.cancel(true);
timeoutFuture = null;
}
ResponseBody body = response.body();
if (body == null) {
LogUtils.d(TAG, "更新包为空");
idle("", 0);
start = false;
return;
}
boolean result = FileIOUtils.writeFileFromIS(updateApk, body.byteStream());
AppUtils.AppInfo info = AppUtils.getApkInfo(updateApk); AppUtils.AppInfo info = AppUtils.getApkInfo(updateApk);
LogUtils.d(TAG, "更新包下载: " + (result ? "成功" : "失败") + ",开始安装: " + (info == null ? "null" : info.getPackageName())); LogUtils.d(TAG, "更新包下载成功,开始安装: " + (info == null ? "null" : info.getPackageName()));
if (info == null || !info.getPackageName().equals(BuildConfig.APPLICATION_ID)) { if (info == null || !info.getPackageName().equals(BuildConfig.APPLICATION_ID)) {
FileUtils.delete(updateApk); FileUtils.delete(updateApk);
idle("", 0); idle("", 0);
......
...@@ -21,6 +21,7 @@ allprojects { ...@@ -21,6 +21,7 @@ allprojects {
repositories { repositories {
google() google()
jcenter() jcenter()
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment