I am trying to convert my singleton CookieUtil
to be injected with Dagger into LoginActivity
. CookieUtil
takes an application context
therefor I have set up the following structure :
AndroidModule
@Module(
injects = {
CookieUtil.class,
LoginActivity.class
},
library = true
)
public class AndroidModule {
private final App application;
public AndroidModule(App application) {
this.application = application;
}
/**
* Allow the application context to be injected but require that it be annotated with
* {@link ForApplication @Annotation} to explicitly differentiate it from an activity context.
*/
@Provides
@Singleton
@ForApplication
Context provideApplicationContext() {
return application;
}
@Provides
@Singleton
CookieUtil provideCookieUtil() {
return new CookieUtil();
}
}
CookieUtil (What I want to inject into LoginActivity)
@Singleton
public class CookieUtil {
@Inject Context mContext; // gets injected with a app context. is this right ?
private PersistentCookieStore persistentCookieStore;
private CookieUtil() {
// use injected mContext
persistentCookieStore = new PersistentCookieStore(mContext);
// ...
}
}
LoginActivity (Where I want to inject CookieUtil)
public class LoginActivity extends BaseActivity {
@Inject CookieUtil cookieUtil;
@Override
protected void onCreate(Bundle savedInstanceState) {
// use CookieUtil ...
}
}
I have also set up all the bootstraping stuff from Dagger examples to enable everything to work
BaseActivity
public class BaseActivity extends ActionBarActivity {
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Perform injection so that when this call returns all dependencies will be available for use.
((App) getApplication()).inject(this);
}
}
App
public class App extends Application {
private ObjectGraph graph;
public void onCreate() {
super.onCreate();
graph = ObjectGraph.create(getModules().toArray());
// ...
}
protected List<Object> getModules() {
return Arrays.asList(
new AndroidModule(this),
new CupsModule() // Another module I haven't listed
);
}
public void inject(Object object) {
graph.inject(object);
}
}
ForApplication
@Qualifier
@Retention(RUNTIME)
public @interface ForApplication {
}
When I run the code, I get
No injectable members on android.content.Context. Do you want to add
an injectable constructor? required by CookieUtil for AndroidModule
What am I doing wrong ?
Everything still looks like magic to me as I don't fully aware of how to wire everything up, so detailed explanation would be very much appreciated.
Also, would be helpful if someone could point me to an explanation on dagger modules, when does it make sense to separate into two different modules ? What logical pieces do they usually bind ?
Thanks
EDIT
Changed suggested by Christian Gruber
@Singleton
public class CookieUtil {
private Context mContext;
private PersistentCookieStore persistentCookieStore;
@Inject
public CookieUtil(Context context) {
// use injected context
mContext = context
persistentCookieStore = new PersistentCookieStore(mContext);
// ...
}
}