java-匕首:android.content.Context上没有可注入成员.您是否要添加可注入的构造函数?类要求的模块

我正在尝试将要与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种事物,则将无法管理您的图形. (蛇声)

上一篇:源码解析之–YYAsyncLayer异步绘制


下一篇:java.lang.RuntimeException: Cannot create an instance of class com.xxx.xxxViewModel