I am developing an Android application that makes use of the MVVM architecture. My problem is that my repository (that is responsible for fetching JSON from the web) needs access to a context.
I've read several suggestions on StackOverflow. So far the most reasonable options I've gathered are the following:
Use Dagger 2 to somehow inject the context.
Let my ViewModel
extend from AndroidViewModel
to get the application context and pass that to the repo.
As of right now I have one ViewModel
and one Repo
RoomFragmentViewModel.java:
public class MyViewModel extends ViewModel {
private MutableLiveData<List<JSONObject>> rooms;
private Repository repository;
public void init(){
if(rooms != null){
return;
}
repository = repository.getInstance();
rooms = repository.getRooms();
}
Repository.java:
public class Repository {
private static Repository instance;
private ArrayList<JSONObject> actualRooms = new ArrayList<>();
public static Repository getInstance() {
if (instance == null) {
instance = new Repository();
}
return instance;
}
public MutableLiveData<List<JSONObject>> getRooms() {
...
}
private void setRooms() {
...
// Here I am fetching data from my server, but in order to to do so I require a context
String url = "http://10.0.0.5:8000/api";
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
(Request.Method.GET, null, new Response.Listener<JSONObject>() {...
// Context needs to be provided right here:
MySingleton.getInstance(context).addToRequestQueue(jsonObjectRequest);
}
}
Due to contradictory statements on the Internet I am unsure how I should resolve this problem. If your answer makes use of dagger could you be so nice to provide an explanation with code since I am completely new to dagger. Thank you in advance.
I ended up injecting the context via dagger. However, from my point of view making your ViewModel
extend from AndroidViewModel
is also an valid option and definitely the easier one. If I were developing an simple and small application I would probably recommend just extending from AndroidViewModel
to avoid unnecessary boilerplate code from dagger.
I followed the dagger series from codingwithmith in order to implement my own solution. So his channel might be useful for future readers: https://www.youtube.com/channel/UCoNZZLhPuuRteu02rh7bzsw/featured
Using Android Hilt
//Dagger - Hilt
def hilt_version = "2.31.2-alpha"
implementation "com.google.dagger:hilt-android:$hilt_version"
kapt "com.google.dagger:hilt-android-compiler:$hilt_version"
def hilt_viewmodel_version = "1.0.0-alpha03"
implementation "androidx.hilt:hilt-lifecycle-viewmodel:$hilt_viewmodel_version"
kapt "androidx.hilt:hilt-compiler:$hilt_viewmodel_version"
.
@Module
@InstallIn(SingletonComponent::class)
class AppModule {
@Singleton
@Provides
fun provideContext(application: Application): Context = application.applicationContext
}
Then pass it via constructor
class MyRepository @Inject constructor(private val context: Context) {
...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With