Commit 7af38e68 by pye52

优化日志上传指令及下载进度指令的执行

1、现在日志上传会准确复制目标文件到临时文件夹中,而非将临时文件夹作为文件不断写入
2、优化更新包下载的方案,通过拦截器的方式监听下载进度(自定义ResponseBody),下载流程也重新调整
parent ecaa2fdd
......@@ -15,12 +15,12 @@ import retrofit2.converter.scalars.ScalarsConverterFactory;
public class SCRetrofit {
private static final long TIMEOUT = 10;
public static SCApi createApi() {
Retrofit retrofit = createRetrofit();
public static SCApi createApi(OkHttpClient client) {
Retrofit retrofit = createRetrofit(client);
return retrofit.create(SCApi.class);
}
public static OkHttpClient createOkHttpClient() {
public static OkHttpClient.Builder createOkHttpClient() {
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.connectTimeout(TIMEOUT, TimeUnit.SECONDS)
.readTimeout(TIMEOUT, TimeUnit.SECONDS)
......@@ -31,11 +31,10 @@ public class SCRetrofit {
interceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);
builder.addInterceptor(interceptor);
}
return builder.build();
return builder;
}
private static Retrofit createRetrofit() {
OkHttpClient client = createOkHttpClient();
private static Retrofit createRetrofit(OkHttpClient client) {
return new Retrofit.Builder()
.client(client)
.baseUrl(BuildConfig.MainHttpServerHost)
......
......@@ -25,6 +25,7 @@ import java.util.Locale;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.RequestBody;
import retrofit2.Response;
......@@ -130,7 +131,7 @@ public class LogCommandHandler extends CommandHandler {
}
}
private boolean copyTargetFiles(File src, File desc) {
private boolean copyTargetFiles(File src, File descDir) {
FileFilter filter = file -> {
Date date = new Date(file.lastModified());
return date.after(startTime) && date.before(endTime);
......@@ -138,14 +139,17 @@ public class LogCommandHandler extends CommandHandler {
List<File> logFiles = FileUtils.listFilesInDirWithFilter(src, filter, false, null);
boolean copyResult = true;
progress("筛选目标日志文件", 10);
File descFile;
for (File file : logFiles) {
copyResult = copyResult && FileUtils.copy(file, desc);
descFile = new File(descDir, file.getName());
copyResult = copyResult && FileUtils.copy(file, descFile);
}
return !logFiles.isEmpty() && copyResult;
}
private void upload(File zip) {
SCApi api = SCRetrofit.createApi();
OkHttpClient client = SCRetrofit.createOkHttpClient().build();
SCApi api = SCRetrofit.createApi(client);
CommandLog.CommandLogData data = commandLog.getData();
String fileNameForServer = data.getLogType() +
"_" + format.format(startTime) +
......
package com.bgycc.smartcanteen.command;
import android.os.Build;
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.DangerousUtils;
import com.blankj.utilcode.util.AppUtils;
import com.blankj.utilcode.util.FileIOUtils;
......@@ -13,7 +16,6 @@ import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.PathUtils;
import com.google.gson.Gson;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
......@@ -37,7 +39,17 @@ public class UpdateCommandHandler extends CommandHandler {
public UpdateCommandHandler(Command command, Gson gson, CommandProgressCallback callback) {
super(command, gson, callback);
this.httpClient = SCRetrofit.createOkHttpClient();
this.httpClient = SCRetrofit.createOkHttpClient()
.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);
progress("下载进度: " + per, per);
}))
.build();
})
.build();
this.commandUpdate = gson.fromJson(command.getData(), CommandUpdate.class);
this.updateApk = new File(PathUtils.getExternalStoragePath(), UPDATE_APK);
FileUtils.delete(updateApk);
......@@ -54,24 +66,33 @@ public class UpdateCommandHandler extends CommandHandler {
.build();
try {
Response response = httpClient.newCall(request).execute();
progress("开始下载", 0);
ResponseBody body = response.body();
if (body == null) {
return failed("请求异常");
}
progress("开始下载", 0);
boolean success = FileIOUtils.writeFileFromIS(updateApk, new BufferedInputStream(body.byteStream()),
p -> progress("下载进度: " + ((int) p), (int) p));
if (success) {
progress("下载完毕,开始安装更新包", 100);
Thread.sleep(INSTALL_DELAY);
AppUtils.AppInfo info = AppUtils.getApkInfo(updateApk);
if (info == null ||
(info.getPackageName().equals(BuildConfig.APPLICATION_ID) && info.getVersionCode() < BuildConfig.VERSION_CODE)) {
return failed("不允许安装低版本");
} else {
DangerousUtils.installAppSilent(updateApk);
return success("安装更新包");
if (!FileIOUtils.writeFileFromIS(updateApk, body.byteStream())) {
return failed("更新包下载失败");
}
progress("下载完毕,开始安装更新包", 100);
Thread.sleep(INSTALL_DELAY);
AppUtils.AppInfo info = AppUtils.getApkInfo(updateApk);
if (info == null ||
(info.getPackageName().equals(BuildConfig.APPLICATION_ID) && info.getVersionCode() < BuildConfig.VERSION_CODE)) {
return failed("不允许安装低版本");
} else {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {
// 6.0及以下安装包需要修改权限才能安装
try {
Process p = Runtime.getRuntime().exec("chmod 755 " + updateApk);
p.waitFor();
} catch (Exception e) {
return failed("更新包安装异常");
}
}
DangerousUtils.installAppSilent(updateApk);
return success("安装更新包");
}
} catch (IOException e) {
LogUtils.e(TAG, "下载更新包失败: " + e.getMessage());
......
package com.bgycc.smartcanteen.entity;
import com.bgycc.smartcanteen.listener.DownloadProgressListener;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import okhttp3.MediaType;
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.BufferedSource;
import okio.ForwardingSource;
import okio.Okio;
import okio.Source;
public class ProgressResponseBody extends ResponseBody {
private final ResponseBody responseBody;
private final DownloadProgressListener listener;
private BufferedSource bufferedSource;
public ProgressResponseBody(ResponseBody responseBody, DownloadProgressListener listener){
this.responseBody = responseBody;
this.listener = listener;
}
@Override
public MediaType contentType() {
return responseBody.contentType();
}
@Override
public long contentLength() {
return responseBody.contentLength();
}
@NotNull
@Override
public BufferedSource source() {
if (null == bufferedSource){
bufferedSource = Okio.buffer(source(responseBody.source()));
}
return bufferedSource;
}
private Source source(Source source) {
return new ForwardingSource(source) {
long totalBytesRead = 0L;
@Override
public long read(@NotNull Buffer sink, long byteCount) throws IOException {
long bytesRead = super.read(sink, byteCount);
totalBytesRead += bytesRead != -1 ? bytesRead : 0;
listener.onProgress(totalBytesRead, responseBody.contentLength(), bytesRead == -1);
return bytesRead;
}
};
}
}
package com.bgycc.smartcanteen.listener;
public interface DownloadProgressListener {
/**
* @param progress 已经下载或上传字节数
* @param total 总字节数
* @param done 是否完成
*/
void onProgress(long progress, long total, boolean done);
}
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