'Pass context with Hilt from ViewModel to data source

I'm trying to use Hilt to pass context along to my data source class, below:

public class PostDataSource extends PageKeyedDataSource<Integer, Post> {

    // we will start from the first page which is 1
    public static final int PAGE_SIZE = 25;

    // we will start from the first page which is 1
    private static final int FIRST_PAGE = 1;

    // this will be called once to load the initial data
    @Override
    public void loadInitial(@NonNull LoadInitialParams<Integer> params, @NonNull final LoadInitialCallback<Integer, Post> callback) {
        // I NEED TO CALL CONTEXT HERE

    }
}

PostDataSource has a data source factory:

public class PostDataSourceFactory extends DataSource.Factory {

    //creating the mutable live data
    private MutableLiveData<PageKeyedDataSource<Integer, Post>> itemLiveDataSource = new MutableLiveData<>();

    @Override
    public DataSource<Integer, Post> create() {
        //getting our data source object
        PostDataSource postDataSource = new PostDataSource();

        //posting the datasource to get the values
        itemLiveDataSource.postValue(postDataSource);

        //returning the datasource
        return postDataSource;
    }


    //getter for itemlivedatasource
    public MutableLiveData<PageKeyedDataSource<Integer, Post>> getItemLiveDataSource() {
        return itemLiveDataSource;
    }
}

And finally, here is the ViewModel class. This ViewModel is called from my fragment:

public class PostViewModel extends ViewModel {

    //creating livedata for PagedList  and PagedKeyedDataSource
    public LiveData<PagedList<Post>> itemPagedList;
    LiveData<PageKeyedDataSource<Integer, Post>> liveDataSource;

    //constructor
    public PostViewModel() {
        //getting our data source factory
        PostDataSourceFactory postDataSourceFactory = new PostDataSourceFactory();

        //getting the live data source from data source factory
        liveDataSource = postDataSourceFactory.getItemLiveDataSource();

        //Getting PagedList config
        PagedList.Config pagedListConfig =
                (new PagedList.Config.Builder())
                        .setEnablePlaceholders(false)
                        .setPageSize(PostDataSource.PAGE_SIZE).build();

        //Building the paged list
        itemPagedList = (new LivePagedListBuilder(postDataSourceFactory, pagedListConfig))
                .build();
    }
}

I don't understand how I would get context in PostDataSource using Hilt's dependency injection.

I've tried doing something like this, but not really sure how to proceed:

public class PostDataSource extends PageKeyedDataSource<Integer, Post> {

    private Context context;

    @Inject
    PostDataSource(@ActivityContext Context context) {
        this.context = context;
    }

    ...

}


Solution 1:[1]

The idea behind DI is to avoid having object creation in your code. You may want to inject PostDataSourceFactory as well.

Context in your PostDataSource will be injected from the generated modules in ActivityComponent or FragmentComponent. This comes out of box for Hilt.

You need to annotate the constructor of your factory so you can use Provider<> to create your source, instead of doing it manually:

public class PostDataSourceFactory extends DataSource.Factory {
    private Provider<PostDataSource> mSourceProvider;
    
    @Inject
    public PostDataSourceFactory(Provider<PostDataSource> sourceProvider){
        mSourceProvider = sourceProvider
    }

    //creating the mutable live data
    private MutableLiveData<PageKeyedDataSource<Integer, Post>> itemLiveDataSource = new MutableLiveData<>();

    @Override
    public DataSource<Integer, Post> create() {
        //getting our data source object
        PostDataSource postDataSource = mSourceProvider.get()

        //posting the datasource to get the values
        itemLiveDataSource.postValue(postDataSource);

        //returning the datasource
        return postDataSource;
    }


    //getter for itemlivedatasource
    public MutableLiveData<PageKeyedDataSource<Integer, Post>> getItemLiveDataSource() {
        return itemLiveDataSource;
    }
}

You also need to inject PostDataSource constructor.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Nikola Despotoski