'Check for work items from w/in a class for usage in a "batch" process and viewable in a settings screen - challenged w/LiveData or ListenableFuture
I'm probably making this harder than it is, but I want to encapsulate logic within a class so I can call it from two places and it is consistent. I want to check to see if:
- All enqueued work is completed
- If there are any un-synced records
If both of these things are true I want to:
- Pull the next 10 records and enqueue them
I guess I am trying to avoid a bunch of things being enqueued at once in case we get behind. On starting up the app, I will run this check, and from the Settings fragment the work will be listed/viewable (so I have a way to understand what is happening in case of trouble...like can delete a work item). Here are two methods in the helper class.
public static WorkQuery getWorkQuery() {
//check to see if the workerManager is free or busy
return WorkQuery.Builder
.fromTags(Arrays.asList("scenarioRun"))
.addStates(Arrays.asList(
WorkInfo.State.FAILED,
WorkInfo.State.ENQUEUED,
WorkInfo.State.RUNNING,
WorkInfo.State.BLOCKED))
.build();
}
public void enqueueNextBatch() {
Log.d(TAG, "enqueueNextBatch: ");
//here is where I would like to see if there is any unfinished work in the queue
ScenarioRunRepository repository = new ScenarioRunRepository(context);
Log.d(TAG, "enqueueNextBatch: getting scenarioList");
List<ScenarioRun> scenarioList = repository.getNextSyncBatch();
CloudSync cloudSync = new CloudSync.Builder()
.setContext(context)
.build();
for (ScenarioRun scenarioRun: scenarioList) {
Log.d(TAG, "enqueueNextBatch: " + scenarioRun.displayName());
// I have the code to enqueue a scenarioRun
}
}
When I am in the settings fragment I use this:
viewModel.setWorkInfoList(WorkManager.getInstance(getContext()).getWorkInfosLiveData(SyncManager.getWorkQuery()));
viewModel.getWorkInfoList().observe(getViewLifecycleOwner(), workInfoObserver);
and have an observer:
final Observer<List<WorkInfo>> workInfoObserver = new Observer<List<WorkInfo>>() {
@Override
public void onChanged(List<WorkInfo> workInfos) {
workerAdapter.setWorkers(workInfos);
}
};
I wanted to batch the work in the class, so my code to call this on startup would be:
Executors.newSingleThreadExecutor().execute(new Runnable() {
@Override
public void run() {
Log.d(TAG, "run: ");
SyncManager syncManager = new SyncManager(getContext());
syncManager.enqueueNextBatch();
}
});
I don't know if it's better to try to make this work with ListenableFuture of LiveData...or if I am approaching this completely wrong. Do I have the Observer/ListenableFuture in the class? Does anybody some sample code to help?
I always seem to struggle w/having a batch process (unattended) which shares logic with an interactive process. Obviously I'm not an expert programmer, but even the enqueueing a worker forced me to "de-callbackify" my process. Probably an area I need to invest more time in understanding, but hopefully a response here will help.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
