处理 WorkManager 对网络连接失败的响应

Handle response of WorkManager on Network connection Failure

我正在使用 WorkManager 将数据从本地 Room 数据库同步到服务器。问题是 Room 在 Loop.MainLooper() 中构建数据库时出错,当我按照以下方式使用它时它工作正常。但是我无法 return 'WorkerResult' 成功或基于任务完成重试。网络丢失时如何停止worker?

public class TestSyncManager extends Worker {

    private final WorkerResult[] workerResult = {WorkerResult.SUCCESS};
    // @Inject            // Dagger2 has not added the support for dependency injection in worker yet.
    private ApiHeader mApiHeader;
    private HandlerThread mHandlerThread;
    private Handler mHandler;
    private Runnable mRunnable;
    private DataManager dataManager;

    @NonNull
    @Override
    public WorkerResult doWork() {
        try {
            //Looper.prepare();
                CommonUtils.Log("usm_work_manager_1", "Work is Started.");

                try {
                    checkNextCall();
                } catch (Exception e) {
                    e.printStackTrace();
                    setWorkerResult(WorkerResult.FAILURE);
                }
            };
            //mHandler = new Handler(Looper.myLooper());
            mHandlerThread = new HandlerThread("LikesHandlerThread");
            mHandlerThread.start();

            Looper looper = mHandlerThread.getLooper();
            mHandler = new Handler(looper);
            mHandler.post(mRunnable);
            //Looper.loop();


            return workerResult[0];
        } catch (Exception e) {
            e.printStackTrace();
            setWorkerResult(WorkerResult.FAILURE);
            return workerResult[0];
        }
    }

    private void checkNextCall() {
        List<LikeAction> likeActions = dataManager.getPendingLikeActions();
        CommonUtils.Log("usm_like_actions", "count= " + likeActions.size());
        if (likeActions.size() > 0) {
            LikeAction likeAction = likeActions.get(0);
            if (NetworkUtils.isNetworkConnected(getApplicationContext())) {
                dataManager.updateProcessingStatus(ActionType.LIKE_ACTION, likeAction.postId);
                requestLikesSync(likeAction);
            } else
                setWorkerResult(WorkerResult.RETRY);
        } else {
            setWorkerResult(WorkerResult.SUCCESS);
        }

    }

    @SuppressLint("CheckResult")
    private void requestLikesSync(LikeAction likeAction) {

                   /* int[] postIds = new int[likeActions.size()];
            for (int i = 0; i < likeActions.size(); i++) {
                postIds[i] = likeActions.get(i).postId;
            }*/
        LikeActionRemote.Request requestObj = new LikeActionRemote.Request(likeAction);

        String apiUrl = ApiEndPoint.BASE_URL + ApiEndPoint.LIKE_ACTION;

        try {
            LikeActionRemote.Response response = dataManager.doLikeActionApiCall(apiUrl, requestObj).blockingGet();
            Log.d("usm_response", "data= " + new Gson().toJson(response));
            if (response.isSuccess())
                dataManager.deleteProcessedActionById(ActionType.LIKE_ACTION, likeAction.postId);

            checkNextCall();
        } catch (Exception e) {
            e.printStackTrace();
        }
        CommonUtils.Log("usm_worker_network", "isNetworkConnected= " + NetworkUtils.isNetworkConnected(getApplicationContext()));
    }

    /**
     * This function will set the result of Worker and
     * it will clear Handler and will quit looper to let
     * the thread exit.
     *
     * @param result WorkResult (Success,Retry or Failure)
     */
    private void setWorkerResult(WorkerResult result) {

        workerResult[0] = result;
        if (mHandlerThread != null) {
            mHandlerThread.getLooper().quit();
            mHandlerThread.getLooper().getThread().interrupt();
            mHandlerThread = null;
            mHandler.getLooper().quit();
            mHandler.removeCallbacks(mRunnable);
            mHandler = null;
        }
    }
}

而不是 .subscribe 使用 .blockingFirst() 运算符。如果您的 api 调用失败,workManger 将重试您的请求:

...
try{
    Response response = dataManager.doLikeActionApiCall(API.URL, requestObj).blockingFirst();
    if(response.isSuccess()){
        return WorkerResult.SUCCESS;
    }else{
        return WorkerResult.RETRY;
    }
}catch (NoSuchElementException|NullPointerException c){
        return WorkerResult.RETRY;       
}