Dagger 2使用不同的URL构建的多个Retrofit实例,用于使用构造函数注入命中不同的API

时间:2016-12-20 10:28:41

标签: java android retrofit2 mvp dagger-2

我很难完成使用mvp的Dagger 2 Retrofit2实现,其中我的应用程序在相应的片段中调用两个不同的api。 我已经定义了限定符注释来为每个Api调用绑定一个Retrofit实例,如下所示

@Qualifier
@Retention(RUNTIME)
public @interface FirstApi{}

@Qualifier
@Retention(RUNTIME)
public @interface SecondApi{}

绑定ApplicationModule中的每个Retrofit

public class ApplicationModule {

private String mBaseUrlFirstApi;
private String mBaseUrlSecondApi;
private Context mContext;

public ApplicationModule(Context context) {
        mContext = context;
    }

...
@Provides 
@FirstApi Retrofit provideFirstApiRetrofit(…) {…}
@Provides
@SecondApi Retrofit provideSecondApiRetrofit(…) {…}

....
}

ApplicationComponent

@Singleton
@Component(modules = ApplicationModule.class)
public interface ApplicationComponent {

    Retrofit exposeRetrofit();

    Context exposeContext();
}

范围

@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface PerActivity {
}

提供ApiService

@Module
public class MyModule {

    @PerActivity
    @Provides
    MyAPIService myApiService(Retrofit retrofit) {
        return retrofit.create(MyAPIService.class);
    }
}

Dagger Injector class

@PerActivity
@Component(modules = MyModule.class, dependencies = ApplicationComponent.class)
public interface MyComponent {

    void inject(Fragment1 fragment1);
    void inject(Fragment2 fragment2);
    // void inject(Fragment3 fragment3);
}

在Application类中,对于单次改装Api调用,我知道这样做:

public class MyApplication extends Application {

    private ApplicationComponent mApplicationComponent;

{...}
 private void initializeApplicationComponents() {
        mApplicationComponent = DaggerApplicationComponent
                .builder()
                .applicationModule(new ApplicationModule(this, "http://api1"))
                .build();
    }

{...}

public ApplicationComponent getApplicationComponent() {
        return mApplicationComponent;
    }

}

但是对于多个url api调用,这不起作用

public class MyApplication extends Application {

    private ApplicationComponent mApplicationComponent;

{...}
 private void initializeApplicationComponents() {
        mApplicationComponent = DaggerApplicationComponent
                .builder()
                .applicationModule(new ApplicationModule(this, "http://api1"))
                .applicationModule(new ApplicationModule(this, "http://api2"))
                .build();
    }

{...}

public ApplicationComponent getApplicationComponent() {
        return mApplicationComponent;
    }
}

这也不是

public class MyApplication extends Application {

    private ApplicationComponent mApplicationComponent;

{...}
 private void initializeApplicationComponents() {
        mApplicationComponent = DaggerApplicationComponentApi1
                .builder()
                .applicationModule(new ApplicationModule(this, "http://api1"))
                .build();

        mApplicationComponent = DaggerApplicationComponentApi2
                .builder()
                .applicationModule(new ApplicationModule(this, "http://api2"))
                .build();
    }

{...}

public ApplicationComponent getApplicationComponent() {
        return mApplicationComponent;
    }

}

解决每个片段中的匕首依赖关系是这样做的

protected resolveDaggerDependency() {
    DaggerFragmentComponent
            .builder()
            .applicationComponent(getApplicationComponent)
            .myModule(new MyModule.class)
            .build.inject(this);
}

BaseFragment类有

public abstract class BaseFragment extends Fragment {

{...}
{...}
{...}

@CallSuper
protected void onViewReady(Bundle savedInstanceState, Intent intent) {
    resolveDaggerDependency(); // to be used by child fragments

protected ApplicationComponent getApplicationComponent() {
    return ((MyApplication)getActivity().getApplication()).getApplicationComponent;
}

}

1 个答案:

答案 0 :(得分:-1)

致电之前

mApplicationComponent = DaggerApplicationComponent
                .builder()
                .applicationModule(new ApplicationModule(this, "http://api1"))
                .applicationModule(new ApplicationModule(this, "http://api2"))
                .build();

制作项目并使用代码完成功能,以查看Android Studio告诉您的组件构建器可用的内容。我的预感是你的应用程序模块的构造函数不同时使用上下文和字符串。一旦你改变了构造函数,就说吧

ApplicationModule(Context context, String url1, String url2) {...}

然后您需要做的就是更改注入代码以删除.applicationModule的第二行,并更改第一行以匹配新的构造函数,即:

mApplicationComponent = DaggerApplicationComponent
                .builder()
                .applicationModule(new ApplicationModule(this, "http://api1", "http://api2"))
                .build();