Android WorkManager returns 多个结果

Android WorkManager returns multiple Results

我是 WorkManager 的新手(也是 Java 的新手),似乎遇到了一些问题。 基本上,我们有一个应用程序,用户可以在其中将一些记录上传到服务器。

上传它们不是问题。但是,我们希望能够在网络断开连接的情况下继续上传。在做了一些研究之后,我偶然发现了 WorkManager。在观看了多个视频和几个教程后,我们决定试一试。

我让它工作了(有点),但我遇到了一个问题,它 returning 多个结果而不是一个。 我想做的是在所有记录更新后 return 结果(成功或失败),然后使用 AlertDialog 显示它是否成功。 我认为它 return 为工作请求中的每个数据项生成一个结果,而不仅仅是一次。 但我不确定为什么,甚至不知道如何解决它。 当我运行 it 3时,AlertDialogs会出现,前2个不会有正确的信息,但最后一个有。

细分: 单击上传按钮时,我调用 UpLoadBatchRecords 方法。 UploadBatchRecords方法设置Data,Constraints,入队WorkRequest:

public void UploadBatchRecords() {
        BatchMaster batchMaster = batchList.get(curBatchPosition);
        final Data data = new Data.Builder()
                .putInt(String.valueOf(NetworkConnected.CUR_POSITION), curBatchPosition)
                .putString(NetworkConnected.currentModule, batchMaster.ModuleName)
                .putString(NetworkConnected.currentBatch, batchMaster.BatchID)
                .build();

        Constraints constraints = new Constraints.Builder()
                .setRequiredNetworkType(NetworkType.CONNECTED)
                .build();


        final OneTimeWorkRequest workRequest = new OneTimeWorkRequest.Builder(NetworkConnected.class)
                .setInputData(data)
                .setConstraints(constraints)
                .build();

        WorkManager.getInstance().enqueue(workRequest);

        WorkManager.getInstance().getWorkInfoByIdLiveData(workRequest.getId())
                   .observe(this, new Observer<WorkInfo>() {
                               @Override
                               public void onChanged(WorkInfo workInfo) {
                                   if (workInfo.getState().isFinished() && workInfo.getState() == WorkInfo.State.SUCCEEDED) {
                                       message = workInfo.getOutputData().getString(NetworkConnected.KEY_SUCCESS);
                                   }
                                   else {
                                       message = workInfo.getOutputData().getString(NetworkConnected.KEY_FAILURE);
                                   }

                                   alert(message);
                               }
                           });
    }

工人阶级:

public class NetworkConnected extends Worker {
    public NetworkConnected(@NonNull Context context, @NonNull WorkerParameters workerParams) {
        super(context, workerParams);
    }

    private ArrayList<BatchMaster> batchList;
    public static final int CUR_POSITION = 0;
    public static final String currentModule = "Module Name";
    public static final String currentBatch = "Batch ID";
    public static final String KEY_SUCCESS = "Success";
    public static final String KEY_FAILURE = "Failure";

        @NonNull
    @Override
    public Result doWork() {
            int curPosition = getInputData().getInt(String.valueOf(CUR_POSITION), 0);
            String moduleName = getInputData().getString(currentModule);
            String batchID = getInputData().getString(currentBatch);
            LoadBatches();

            try {

                UploadBatchRecords(curPosition, moduleName, batchID);

                Data success = new Data.Builder()
                        .putString(KEY_SUCCESS, " records have been updated \n\n")
                        .build();

                return Result.success(success);
            }
            catch (Exception e) {
                Data failure = new Data.Builder()
                        .putString(KEY_FAILURE, " records failed to upload")
                        .build();
                return Result.failure(failure);
            }
        }

    public void UploadBatchRecords(Integer curPosition, String modName, String batchID) {
        int seqNum;
        String recordData;

        Cursor cur = Global.dbManager.fetchBatchRecords(companyID, modName, batchID);
        while (cur.moveToNext()) {
            seqNum = cur.getInt(cur.getColumnIndex("SequenceNumber"));
            recordData = cur.getString(cur.getColumnIndex("RecordData"));

            BatchRecordWebService(curPosition, seqNum, recordData);
        }
        cur.close();
    }

    public void BatchRecordWebService(Integer position, Integer seqNum, String recordData) {
        BatchMaster batchMaster = batchList.get(position);

        final WebService webservice = new WebService();

        webservice.setMethodName("UploadRecord");
        ArrayList<PropertyInfo> props = new ArrayList<>();
        AddWebServiceProperty(props, "CompanyID", companyID, String.class);
        AddWebServiceProperty(props, "ModuleName", batchMaster.ModuleName, String.class);
        AddWebServiceProperty(props, "BatchID", batchMaster.BatchID, String.class);
        AddWebServiceProperty(props, "SequenceNumber", seqNum.toString(), String.class);
        AddWebServiceProperty(props, "RecordData", recordData, String.class);
        AddWebServiceProperty(props, "CreatedBy", batchMaster.CreatedBy, String.class);
        AddWebServiceProperty(props, "CreatedDate", batchMaster.CreatedDate, String.class);
        AddWebServiceProperty(props, "UploadedBy", batchMaster.UpdatedBy, String.class);
        AddWebServiceProperty(props, "UploadDate", batchMaster.UpdatedDate, String.class);

        webservice.setSoapProperties(props);

        try {
            webservice.execute().get();

            if (webservice.getSuccess()) {
                Global.count++;
            }
            else{
                Global.failedCount++;
            }
        } catch (Exception ignored) {
        }
    }

    public void LoadBatches() {
        batchList = new ArrayList<>();

        Cursor cur = Global.dbManager.fetchBatches();
        while (cur.moveToNext()) {
            BatchMaster view = new BatchMaster(cur.getString(cur.getColumnIndex("ModuleName")),
                    cur.getString(cur.getColumnIndex("BatchID")),
                    cur.getString(cur.getColumnIndex("FormatName")),
                    cur.getInt(cur.getColumnIndex("RecordCount")),
                    cur.getString(cur.getColumnIndex("CreatedBy")),
                    cur.getString(cur.getColumnIndex("CreateDate")),
                    cur.getString(cur.getColumnIndex("UpdatedBy")),
                    cur.getString(cur.getColumnIndex("UpdateDate")));
            batchList.add(view);
        }
        cur.close();
   }

我不确定我错过了什么,我很确定这是愚蠢的。你能提供的任何帮助都会很棒!谢谢!

好吧,这是愚蠢的事情。 已更改

else {
  message = workInfo.getOutputData().getString(NetworkConnected.KEY_FAILURE);
                                       alert(message);
                                   }

                               }
                           });

至:

else if (workInfo.getState() == WorkInfo.State.FAILED) {
                                       message = workInfo.getOutputData().getString(NetworkConnected.KEY_FAILURE);
                                       alert(message);
                                   }

                               }
                           });

where its returning multiple results instead of just one.

这是意料之中的,因为 onChanged() 方法在状态发生任何变化时被调用,无论工作是否完成。

    /**
     * Returns {@code true} if this State is considered finished.
     *
     * @return {@code true} for {@link #SUCCEEDED}, {@link #FAILED}, and * {@link #CANCELLED}
     *         states
     */
    public boolean isFinished() {
        return (this == SUCCEEDED || this == FAILED || this == CANCELLED);
    }

WorkInfo isFinished() 当您的工作处于任何(成功 | 失败 | 取消)状态时调用。

但是还有其他状态,比如ENQUEUED | 运行 |已屏蔽。

因此,onChanged() 方法会在任何这些状态下被调用,

What I'd like to do is just have it return the Result(Success or Failure) once AFTER all the records have been updated and then use an AlertDialog to show whether or not it succeeded.

但是因为你需要它一旦整个工作 returns 一个结果,那么你需要将你的代码包装在 if (workInfo.getState().isFinished()) 中,但是对于 else 中的所有其他状态来说这都是否定的] 分支。

为此:

WorkManager.getInstance().getWorkInfoByIdLiveData(workRequest.getId())
           .observe(this, new Observer<WorkInfo>() {
                       @Override
                       public void onChanged(WorkInfo workInfo) {
                           if (workInfo.getState().isFinished() {
                               if (workInfo.getState() == WorkInfo.State.SUCCEEDED) {
                                   message = workInfo.getOutputData().getString(NetworkConnected.KEY_SUCCESS);
                               }
                               else {
                                   message = workInfo.getOutputData().getString(NetworkConnected.KEY_FAILURE);
                               }

                               alert(message);
                           }
                       }
                   });