一个活动中两个组件的依赖关系

时间:2016-04-01 09:33:36

标签: android dagger-2

我正在玩Dagger-2来计算如何将它集成到我们现有的应用程序中,并且我遇到了一些我无法理解或者我做错了。

我的情况:

3没有任何带注释的构造函数的API(每个都在自己的文件中)

public class DbApi {
   public void doSomething(String username, String password) {
   }
}

public class RestApi {
    public void doSomething(String username, String password) {
    }
}

public class SocketApi {
    public void doSomething(String username, String password) {
    }
}

3个模块(每个模块都在自己的文件中)

@Module
public class DbModule {
    @Provides
    @Singleton
    public DbApi getDbApi(){
        return new DbApi();
    }
}

@Module
public class RestModule {
    @Provides
    @Singleton
    public RestApi getRestApi(){
        return new RestApi();
    }
}

@Module
public class SocketModule {
    @Provides
    @Singleton
    public SocketApi getSocketApi(){
        return new SocketApi();
    }
}

2个组件(每个组件都在自己的文件中)

@Singleton
@Component(modules = {DbModule.class})
public interface DbComponent {
   void inject(SecondActivity activity);
}

@Singleton
@Component(modules = {RestModule.class, SocketModule.class})
public interface NetComponent {
   void inject(MainActivity activity);
}

我将两个组件初始化为我的Aplication

public class MyApplication extends Application {

DbComponent dBComponent;
NetComponent netComponent;

@Override
public void onCreate() {
    super.onCreate();
    dBComponent = DaggerDbComponent.builder().build();
    netComponent = DaggerNetComponent.builder().build();
}

public NetComponent getNetComponent() {
    return netComponent;
}

public DbComponent getdBComponent() {
    return dBComponent;
}
}

通过所有这些定义,我将NetComponent用于一个活动,将DbCompoment用于第二个活动。

进入第一个活动

public class MainActivity extends AppCompatActivity {

@Inject RestApi restApi;
@Inject SocketApi socketApi;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //...
    ((MyApplication) getApplication()).getNetComponent().inject(this);
    //...
}
}

并进入第二个

public class SecondActivity extends AppCompatActivity {

@Inject DbApi dbApi;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //...
    ((MyApplication) getApplication()).getdBComponent().inject(this);
    //...
}
}

到目前为止一切正常,我在每项活动中都注入了适当的东西。 但后来我意识到RestApiSocketApi也需要进入SecondActity,所以我试着将它们注入活动中,在这里我有疑问和问题。

我修改了NetComponent以添加以下行

void inject(SecondActivity activity);

我修改了SecondActivity

public class SecondActivity extends AppCompatActivity {

@Inject DbApi dbApi;
@Inject RestApi restApi;
@Inject SocketApi socketApi;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //...
    ((MyApplication) getApplication()).getdBComponent().inject(this);
    ((MyApplication) getApplication()).getNetComponent().inject(this);
    //...
}
}

在编译我的项目的那些修改后,我有以下错误

错误:(15,10)错误:如果没有@Inject构造函数或@ Provide-或@ Produces-annotated方法,则无法提供com.example.guillaume.testdagger.RestApi。     com.example.guillaume.testdagger.SecondActivity.restApi     [注入字段类型:com.example.guillaume.testdagger.RestApi restApi]

错误:(16,10)错误:如果没有@Inject构造函数或@ Provide-或@ Produces-annotated方法,则无法提供com.example.guillaume.testdagger.DbApi。 com.example.guillaume.testdagger.SecondActivity.dbApi [注入字段类型:com.example.guillaume.testdagger.DbApi dbApi]

所以我的问题是:

  • 这个错误来自哪里?
  • 如何使用多个组件将字段注入一个活动
  • 我做错了,组织组件/模块的最佳方法是什么才能将一个组件重用到已经包含另一个模块的活动中
  • 我可以通过将@Inject注释的空公共构造函数添加到我的api类来修复错误但是这样做我发现我的所有字段都会被注入SecondActivity而不管用于调用inject的组件是什么{1}}方法,这是正确的方法。

1 个答案:

答案 0 :(得分:6)

啊...我分享你的痛苦。 您不能将两个组件注入同一个Activity。至少我无法找到怎么样! :)

这对我来说也是合乎逻辑的,我也遇到了同样的问题。

您可以使用2种方法解决它:

  1. 为所有注射使用一个大组件(我真的是那个)
  2. 为每个要注入内容的活动/场所创建一个组件
  3. 所以,而不是

    @Singleton
    @Component(modules = {RestModule.class, SocketModule.class})
    public interface NetComponent {
       void inject(MainActivity activity);
    }
    

    尝试

    @Singleton
    @Component(modules = {RestModule.class, SocketModule.class, DbModule.class})
    public interface SecondActivityComponent {
       void inject(SecondActivity activity);
    }
    

    我发现第二个是最干净的解决方案。

    如果有人有其他建议,我准备尝试了!