我正在尝试将要与Dagger一起注入的单身CookieUtil转换为LoginActivity. CookieUtil为此具有应用程序上下文,我已经建立了以下结构:
Android模块
@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(我想注入到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(我要在其中注入CookieUtil的位置)
公共类LoginActivity扩展BaseActivity {
@Inject CookieUtil cookieUtil;
@Override
protected void onCreate(Bundle savedInstanceState) {
// use CookieUtil ...
}
}
我还设置了Dagger示例中的所有引导程序,以使一切正常工作
基础活动
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);
}
}
应用程式
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);
}
}
申请
@Qualifier
@Retention(RUNTIME)
public @interface ForApplication {
}
当我运行代码时,我得到
No injectable members on android.content.Context. Do you want to add
an injectable constructor? required by CookieUtil for AndroidModule
我究竟做错了什么 ?
对我来说,一切仍然看起来像魔术,因为我不完全了解如何将所有内容连接起来,因此,非常感谢您提供详细的解释.
此外,如果有人可以指出我对dagger模块的解释,将它分成两个不同的模块什么时候有意义?它们通常绑定哪些逻辑块?
谢谢
编辑
由克里斯蒂安·格鲁伯(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);
// ...
}
}
解决方法:
Cookie不能具有私有构造函数,并且仍由Dagger创建(提供).您可以有一个对程序包友好的构造函数,然后它可以在没有@Provides CookiUtil …的情况下正常工作.
一般来说,Dagger会根据其类型(带有具体的类型参数,例如Foo< Bar>)以及任何@Qualifier来考虑根据“键”进行“绑定”.因此,类型Foo< Bar>与@ForApplication Foo< Bar>不同.无论@Inject发生在哪里,都将请求绑定,并且@Provides发生的地方将提供绑定(或者对于不合格的绑定,如果类具有@Inject标记的构造函数或字段,则提供隐式绑定.对于每个@Inject字段或构造函数参数Dagger必须能够看到它用于创建事物的方法,因此通常不可能使用私有字段,方法和构造函数.
另外,请不要在没有限定符的情况下简单地注入Context.或更佳的是,如果您要表示的是Context子类型,则注入Application或Activity.如果您不区分Android称为Context子类型的30,000种事物,则将无法管理您的图形. (蛇声)