Note: See update 2 for what I currently have
Currently in my fragment's onCreateView(), I have an adapter for a recyclerview initialized like this:
Query query = couchLocalDb.getDatabase().getView(MY_VIEW_NAME).createQuery();
LiveQuery liveQuery = query.toLiveQuery();
if (myAdapter == null) {
myAdapter = new MyAdapter(getActivity().getApplication(), new ArrayList<>(), getActivity(), liveQuery);
}
And this is the constructor of the said adapter:
public MyAdapter(Application application,
List<MyViewHolder> myViewHolderList,
Context context,
LiveQuery liveQuery) {
this.myViewHolderList = myViewHolderList;
this.context = context;
this.liveQuery = liveQuery
LiveQuery.ChangeListener listener = new LiveQuery.ChangeListener() {
@Override
public void changed(LiveQuery.ChangeEvent event) {
((Activity)MyAdapter.this.context).runOnUiThread(new Runnable() {
@Override
public void run() {
enumerator = event.getRows();
notifyDataSetChanged();
}
});
}
};
((MainApplication)application).getAppComponent().inject(this);
this.liveQuery.addChangeListener(listener);
this.liveQuery.start();
}
But recently I'm trying to learn how to use Dagger 2 for dependency injection, and I think I shouldn't have "new" anywhere besides in the Dagger's AppModule?
So how would I write the provide method in my AppModule class for this when I need the context of the fragment? Or am I doing this injection completely wrong and totally missed the idea?
The context variable is only ever used in this line:
((Activity)MyAdapter.this.context).runOnUiThread(new Runnable()...
Here's what I have so far in my AppModule class:
@Provides
MyAdapter provideMyAdapter() {
return new MyAdapter(mainApplication, new ArrayList<>(), idk_context, getLiveQuery);
}
private LiveQuery getLiveQuery() {
return couchLocalDb.getDatabase().getView(MY_VIEW_NAME).createQuery().toLiveQuery();
}
I'm not sure how I'm supposed to find a way to use the getActivity() to get the context from my fragment.
Any hint?
Update: Is it okay to do this?
@Module
public class AppModule {
private MyFragment myFragment = new MyFragment(); // So I just initialize this here instead
private MainApplication mainApplication;
public AppModule(MainApplication mainApplication) {
this.mainApplication = mainApplication;
}
@Provides
MyAdapter provideMyAdapter() {
return new MyAdapter(mainApplication, new ArrayList<>(), myFragment.getActivity(), getLiveQuery());
}
@Singleton
@Provides
MyFragment provideMyFragment() {
return myFragment;
}
private LiveQuery getLiveQuery() {
return couchLocalDb.getDatabase().getView(MY_VIEW_NAME).createQuery().toLiveQuery();
}
}
Update 2: I ended up doing this: I added a thing to just provide activity and call it a day. Is this okay to do?
@Module
public class AppModule {
private MainApplication mainApplication;
public AppModule(MainApplication mainApplication) {
this.mainApplication = mainApplication;
}
@Provides
@Singleton
MyAdapter provideMyAdapter(Activity activity, LiveQuery liveQuery) {
return new MyAdapter(mainApplication, new ArrayList<>(), activity, liveQuery);
}
@Provides
@Singleton
MyFragment provideMyFragment() {
return new MyFragment();
}
// I added this method and just let this provide the activity to my provideAdapter method.
@Provides
@Singleton
Activity provideActivity(MyFragment myFragment) {
return myFragment.getActivity();
}
@Provides
@Singleton
LiveQuery provideLiveQuery() {
return couchLocalDb.getDatabase().getView(MY_VIEW_NAME).createQuery().toLiveQuery();
}
}
Here's the new constructor
public MyAdapter(Application application,
List<MyViewHolder> myViewHolderList,
Activity activity,
LiveQuery liveQuery) {
this.myViewHolderList = myViewHolderList;
this.liveQuery = liveQuery
LiveQuery.ChangeListener listener = new LiveQuery.ChangeListener() {
@Override
public void changed(LiveQuery.ChangeEvent event) {
(activity).runOnUiThread(new Runnable() {
@Override
public void run() {
enumerator = event.getRows();
notifyDataSetChanged();
}
});
}
};
((MainApplication)application).getAppComponent().inject(this);
this.liveQuery.addChangeListener(listener);
this.liveQuery.start();
}
Is this a okay thing to do? Not a bad practice or anything?