javaandroidmvvmandroid-workmanagerandroid-mvvm

Which Context will be passed to WorkManager.getInstance()


I am trying to enqueue a WorkManager worker through a repository Method in order to insert some data inside my database but i can't seem to figure out what type of context i should pass inside the getInstance(). Obviously the Context i am giving is wrong since i am getting a NullPointerException. I am new to Android development and the concept of Context can be confusing. I've tried everything but i am sure it's something simple. I am using MVVM (let me know if i should not enqueue a Worker inside the repository) + RoomDatabase.

AddWorkoutRepository.java

public class AddWorkoutRepository {

    private static final String REPOSITORY_TAG = "REPOSITORY TAG";
    private AddWorkoutWorker worker;

    private WorkoutDAO workoutDAO;
    //private LiveData<List<Workout>> workouts;

    public AddWorkoutRepository(Application application){

        AppDatabase database = AppDatabase.getInstance(application);
        workoutDAO = database.workoutDAO();
        //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("Importing Single Workout" + workoutName + " and " + workoutType)
                .build();

        WorkManager.getInstance(worker.getApplicationContext()).enqueue(importDataRequest);

        Log.d(REPOSITORY_TAG, "After work manager task OK");

    }
}

AddWorkoutWorker.java

public class AddWorkoutWorker extends Worker {

    public static final String WORK_WORKOUT_NAME = "workout";
    public static final String WORK_WORKOUT_TYPE = "type";
    private static final String WORKER_TAG = "Worker Tag";
    private WorkoutDAO workoutDAO;

    public AddWorkoutWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
        super(context, workerParams);
    }

    @NonNull
    @Override
    public Result doWork() {

        Data inputData = getInputData();
        String workoutName = inputData.getString(WORK_WORKOUT_NAME);
        String workoutType = inputData.getString(WORK_WORKOUT_TYPE);

        if (workoutName != null && workoutType != null){
            Log.d(WORKER_TAG,"Worker data passed: "+workoutName + workoutType);
            Workout workout = new Workout(workoutName, workoutType);
            workoutDAO.insertSingleWorkout(workout);
        }else{
            return Result.failure();
        }

        return Result.success();
    }
}

If more code is needed feel free to ask me. Thank you so much for the help in advance!


Solution

  • You've got NullPointerException in line WorkManager.getInstance(worker.getApplicationContext()).enqueue(importDataRequest); because worker field is not initialised and it's default value is null. You shouldn't get instance of WorkManager in each insertWorkout(Workout workout) method call. Instead of this pass WorkManager instance as dependency in constructor of AddWorkoutRepository. For the context you can use activity context or application context instead. If you don't like this approach, you can add WorkManager field in AddWorkoutRepository class and initialise it in AddWorkoutRepository constructor and use Application object as a context.

    Update your AddWorkoutRepository class:

    public class AddWorkoutRepository {
    
    private static final String REPOSITORY_TAG = "REPOSITORY TAG";
    private static final String WORK_WORKOUT_NAME = "work_name";
    private static final String WORK_WORKOUT_TYPE = "work_time";
    private final WorkManager workManager;
    private AddWorkoutWorker worker;
    
    private WorkoutDAO workoutDAO;
    //private LiveData<List<Workout>> workouts;
    
    public AddWorkoutRepository(Application application){
    
        AppDatabase 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("Importing Single Workout" + workoutName + " and " + workoutType)
                .build();
    
        workManager.enqueue(importDataRequest);
    
    
        Log.d(REPOSITORY_TAG, "After work manager task OK");
    
    }
    

    }