Commit b5200563 by pye52

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

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