如何解决如何从 Worker 获取输出数据? (MVVM + WorkManager + Room)
我正在使用 MVVM 并将工作人员从我的存储库中排队。工作人员的工作只是将一些数据插入数据库,但我想在后台任务完成后访问一些输出数据,以便我可以验证数据是否顺利进入数据库。我尝试使用 WorkInfo.State 或使用 getOutputData 获取数据,但由于某种原因它似乎不起作用。关于如何实现这一目标的任何想法?
以下是代码供参考:
AddWorkoutWorker.java
public class AddWorkoutWorker extends Worker {
public static final String WORK_WORKOUT_NAME = "workout";
public static final String WORK_WORKOUT_TYPE = "type";
public static final String WORK_FAILURE_TAG = "failed";
public static final String WORK_SUCCESS_TAG = "success";
private static final String WORKER_TAG = "Worker Tag";
private WorkoutDAO workoutDAO;
private AppDatabase database;
Boolean workSuccess;
//Worker constructor
public AddWorkoutWorker(@NonNull Context context,@NonNull WorkerParameters workerParams) {
super(context,workerParams);
database = AppDatabase.getInstance(context);
workoutDAO = database.workoutDAO();
}
@NonNull
@Override
public Result doWork() {
//Gets input data
Data inputData = getInputData();
String workoutName = inputData.getString(WORK_WORKOUT_NAME);
String workoutType = inputData.getString(WORK_WORKOUT_TYPE);
if (workoutName != null && workoutType != null){
//Inserts item in database through DAO
Log.d(WORKER_TAG,"Worker data passed: "+workoutName + workoutType);
Workout workout = new Workout(workoutName,workoutType);
workoutDAO.insertSingleWorkout(workout);
}else{
//Returns false if the worker doesn't add the item to the database
workSuccess = false;
Data output = new Data.Builder()
.putBoolean(WORK_FAILURE_TAG,workSuccess)
.build();
return Result.failure(output);
}
//Returns true if the worker adds the item to the database
workSuccess = true;
Data output = new Data.Builder()
.putBoolean(WORK_SUCCESS_TAG,workSuccess)
.build();
return Result.success(output);
}
}
AddWorkoutRepository.java
public class AddWorkoutRepository{
private static final String REPOSITORY_TAG = "REPOSITORY TAG";
public static final String WORKER_QUEUE_TAG = "Importing Single Workout";
public WorkoutDAO workoutDAO;
private final WorkManager workManager;
private AppDatabase database;
//private LiveData<List<Workout>> workouts;
public AddWorkoutRepository(Application application){
database = AppDatabase.getInstance(application);
workoutDAO = database.workoutDAO();
workManager = WorkManager.getInstance(application.getApplicationContext());
//workouts = workoutDAO.getAllWorkoutsLiveData();
}
/*public LiveData<List<Workout>> getAllWorkouts(){
return workouts;
}*/
public void insertWorkout(Workout workout){
String workoutName = workout.getWorkoutName();
String workoutType = workout.getWorkoutType();
Log.d(REPOSITORY_TAG,"Insert Values passed: "+workoutName + workoutType);
Data data = new Data.Builder()
.putString(WORK_WORKOUT_NAME,workoutName)
.putString(WORK_WORKOUT_TYPE,workoutType)
.build();
OneTimeWorkRequest importDataRequest = new OneTimeWorkRequest.Builder(AddWorkoutWorker.class)
.setInputData(data)
.addTag(WORKER_QUEUE_TAG)
.build();
workManager.enqueue(importDataRequest);
Log.d(REPOSITORY_TAG,"After work manager task OK");
}
}
解决方法
好的,所以我想通了。我使用了 WorkInfo 提供的 LiveData obj 来获取输出数据和任务状态。
- 我做的第一件事是在我的 ViewModel
private LiveData<List<WorkInfo>> workerOutPut;
中声明 LiveData obj - 然后在视图模型构造函数中像这样初始化我的 LiveData
workerOutPut = workManager.getWorkInfosByTagLiveData(ADD_WORKOUT_WORKER_QUEUE_TAG);
- 为 LiveData 制作了一个 getter(当然在 ViewModel 中)
- 然后我只是在我的 Activity 中创建了一个 Observer,它根据我在 Worker 输出数据中设置的布尔值检查 Worker 的状态。
就是这样。我对这一切都很陌生,所以如果有人要添加任何内容,请随时添加。我会为其他新“玩家”发布完整代码以帮助他们。
Worker.java
public class AddWorkoutWorker extends Worker {
public static final String WORK_WORKOUT_NAME = "workout";
public static final String WORK_WORKOUT_TYPE = "type";
public static final String WORK_FAILURE_TAG = "failed";
public static final String WORK_SUCCESS_TAG = "success";
private static final String ADD_WORKOUT_WORKER_TAG = "Worker Tag";
private WorkoutDAO workoutDAO;
private AppDatabase database;
Boolean workSuccess;
//Worker constructor
public AddWorkoutWorker(@NonNull Context context,@NonNull WorkerParameters workerParams) {
super(context,workerParams);
database = AppDatabase.getInstance(context);
workoutDAO = database.workoutDAO();
}
@NonNull
@Override
public Result doWork() {
//Gets input data
Data inputData = getInputData();
String workoutName = inputData.getString(WORK_WORKOUT_NAME);
String workoutType = inputData.getString(WORK_WORKOUT_TYPE);
if (workoutName != null && workoutType != null){
//Inserts item in database through DAO
Log.d(ADD_WORKOUT_WORKER_TAG,"Worker data passed: "+workoutName + workoutType);
Workout workout = new Workout(workoutName,workoutType);
workoutDAO.insertSingleWorkout(workout);
}else{
//Returns false if the worker doesn't add the item to the database
workSuccess = false;
Data output = new Data.Builder()
.putBoolean(WORK_FAILURE_TAG,workSuccess)
.build();
return Result.failure(output);
}
//Returns true if the worker adds the item to the database
workSuccess = true;
Data output = new Data.Builder()
.putBoolean(WORK_SUCCESS_TAG,workSuccess)
.build();
return Result.success(output);
}
}
ViewModel.java
public class AddWorkoutViewModel extends AndroidViewModel {
private static final String WORKOUT_VIEW_MODEL = "Workout View Model";
private AddWorkoutRepository repository;
private AddWorkoutWorker worker;
private WorkManager workManager;
private Boolean check;
private LiveData<List<WorkInfo>> workerOutPut;
//private LiveData<List<Workout>> AllWorkouts;
public AddWorkoutViewModel(@NonNull Application application) {
super(application);
repository = new AddWorkoutRepository(application);
workManager = WorkManager.getInstance(application);
workerOutPut = workManager.getWorkInfosByTagLiveData(ADD_WORKOUT_WORKER_QUEUE_TAG);
//AllWorkouts = repository.getAllWorkouts();
}
/*public LiveData<List<Workout>> getWorkoutList(){
return AllWorkouts;
}*/
public LiveData<List<WorkInfo>> checkWorkerStatus(){
return workerOutPut;
}
public void insertData(Workout workout){
Log.d(WORKOUT_VIEW_MODEL,"View Model Insert Data");
repository.insertWorkout(workout);
}
}
活动内部的观察者
//Observes LiveData from WorkManager AddWorkoutWorker to validate if worker functioned correctly
mAddWorkoutViewModel.checkWorkerStatus().observe(this,new Observer<List<WorkInfo>>() {
@Override
public void onChanged(List<WorkInfo> workInfos) {
if(workInfos.isEmpty() || workInfos == null){
Log.d(ADD_WORKOUT_WORKER_EMPTY,"Worker is empty");
}else{
if(workInfos.get(0).getOutputData().getBoolean(WORK_SUCCESS_TAG,false)){
//If works do stuff here
}else{
Toast.makeText(AddWorkoutActivity.this,"Something went wrong. Try again.",Toast.LENGTH_LONG);
}
}
}
});
对于那些可能想知道的人。我使用 workInfos.get(0) 因为我们只有一个工人正在检查。我假设如果我们同时有多个工人,我们可以为每个工人制定一个案例。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。