package com.example.mydemo.other;
import android.content.Context;
import androidx.annotation.NonNull;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class UploadWorker extends Worker {
private static final int MAX_RETRY = 1;
private static final int STAGE1_WEIGHT = 80;
private static final int STAGE2_WEIGHT = 10;
private static final int STAGE3_WEIGHT = 10;
public UploadWorker(@NonNull Context context, @NonNull WorkerParameters params) {
super(context, params);
}
@NonNull
@Override
public Result doWork() {
try {
List<String> localImageUris = getInputData().getStringArrayList("images");
// ------------ ① 阶段:并发获取结果 (80%) -------------
List<String> obsLinks = runStageWithRetry(() -> runStage1(localImageUris), STAGE1_WEIGHT);
// ------------ ② 阶段:merge 请求 (10%) -------------
String mergeUrl = runStageWithRetry(() -> runStage2(obsLinks), STAGE2_WEIGHT);
// ------------ ③ 阶段:下载结果文件 (10%) -------------
boolean success = runStageWithRetry(() -> runStage3(mergeUrl), STAGE3_WEIGHT);
return success ? Result.success() : Result.failure();
} catch (Exception e) {
e.printStackTrace();
return Result.failure();
}
}
/** -------------------- 重试包装方法 --------------------- */
private <T> T runStageWithRetry(StageTask<T> task, int weight) throws Exception {
for (int retry = 0; retry <= MAX_RETRY; retry++) {
try {
return task.run();
} catch (Exception e) {
if (retry >= MAX_RETRY) throw e; // 最后一次还失败则抛出
}
}
return null;
}
/** -------------------- 阶段1:并发任务 --------------------- */
private List<String> runStage1(List<String> images) throws Exception {
int total = images.size();
ExecutorService executor = Executors.newFixedThreadPool(3);
List<Future<String>> futures = new ArrayList<>();
List<String> results = new ArrayList<>();
for (String img : images) {
futures.add(executor.submit(() -> callPicToWord(img))); // 网络请求方法自己实现
}
for (int i = 0; i < futures.size(); i++) {
String url = futures.get(i).get();
results.add(url);
updateProgress((i + 1), total, STAGE1_WEIGHT);
}
executor.shutdown();
return results;
}
/** -------------------- 阶段2:merge 请求 --------------------- */
private String runStage2(List<String> urls) throws Exception {
String mergeUrl = callMergeWord(urls); // 自己实现
updateProgress(1, 1, STAGE2_WEIGHT);
return mergeUrl;
}
/** -------------------- 阶段3:下载保存 --------------------- */
private boolean runStage3(String downloadUrl) throws Exception {
String base64Word = downloadBase64(downloadUrl); // 网络下载实现
saveToFile(base64Word); // 保存文件实现
updateProgress(1, 1, STAGE3_WEIGHT);
return true;
}
/** -------------------- 进度计算 --------------------- */
private int accumulatedProgress = 0;
private void updateProgress(int current, int total, int weight) {
int stageProgress = (int) (((float) current / total) * weight);
int newProgress = accumulatedProgress + stageProgress;
setProgressAsync(new Data.Builder().putInt("progress", newProgress).build());
if (current == total) accumulatedProgress += weight;
}
/** -------------------- Functional Interface --------------------- */
interface StageTask<T> {
T run() throws Exception;
}
/** -------------------- 以下为伪代码方法 --------------------- */
private String callPicToWord(String uri) throws Exception {
// TODO 网络请求
return "obs_url_xxx";
}
private String callMergeWord(List<String> list) throws Exception {
// TODO 网络请求
return "merge_download_short_link";
}
private String downloadBase64(String shortLink) throws Exception {
// TODO 下载 base64
return "BASE64_STRING";
}
private void saveToFile(String base64) throws Exception {
// TODO 保存本地
//workManager.getWorkInfoByIdLiveData(request.getId())
// .observe(this, info -> {
// if (info != null && info.getProgress().containsKey("progress")) {
// int progress = info.getProgress().getInt("progress", 0);
// progressBar.setProgress(progress);
// }
// });
}
}