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

Gui*_*rré 6 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) {
    }
}
Run Code Online (Sandbox Code Playgroud)

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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);
}
Run Code Online (Sandbox Code Playgroud)

我将这两个组件初始化为我的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;
}
}
Run Code Online (Sandbox Code Playgroud)

通过所有这些定义,我将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);
    //...
}
}
Run Code Online (Sandbox Code Playgroud)

进入第二个

public class SecondActivity extends AppCompatActivity {

@Inject DbApi dbApi;

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

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

我修改我NetComponent添加以下行

void inject(SecondActivity activity);
Run Code Online (Sandbox Code Playgroud)

我修改了我的 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);
    //...
}
}
Run Code Online (Sandbox Code Playgroud)

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

错误:(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方法的组件是什么,我的所有字段都会被注入,这是正确的方法吗这个.

Boz*_*jsa 7

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

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

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

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

所以,而不是

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

尝试

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

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

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