如何使用Dagger2将活动注入片段

时间:2017-06-09 18:49:01

标签: android dagger-2 dagger

我正在尝试将我的MainActivity注入Fragment。我有一个在我的MainActivity中实现的接口,它将侦听Fragment中的事件。所以我想注入MainActivity并在其上调用事件监听器。

我尝试过以下操作,但未能这样做。只显示代码片段。

接口

public interface RecipeItemListener {
    void onRecipeItem();
}

实现接口的MainActivity

public class MainActivity extends AppCompatActivity implements RecipeItemListener {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if(savedInstanceState == null) {
            getSupportFragmentManager()
                    .beginTransaction()
                    .add(R.id.main_fragment_container, RecipeListView.newInstance(), RecipeListView.TAG)
                    .commit();
        }
    }

    @Override
    public void onRecipeItem() {
        Timber.d("onRecipeItem");
    }
}

提供MainActivity的模块

@Module
public class RecipeListModule {
    private MainActivity mainActivity;

    public RecipeListModule(MainActivity mainActivity) {
        this.mainActivity = mainActivity;
    }

    @RecipeListScope
    @Provides
    public RecipeItemListener providesRecipeListMainActivity() {
        return mainActivity;
    }
}

我的主要组件

@Singleton
@Component(modules = {
        AndroidModule.class,
        NetworkModule.class})
public interface BusbyBakingComponent {
    RecipeListComponent add(RecipeListModule recipeListModule);
}

我的子组件

@RecipeListScope
@Subcomponent(modules = {RecipeListModule.class})
public interface RecipeListComponent {
    void inject(RecipeListView target);
}

我的申请类

public class BusbyBakingApplication extends Application {
    private BusbyBakingComponent applicationComponent;
    private RecipeListComponent recipeListComponent;

    @Override
    public void onCreate() {
        super.onCreate();

        applicationComponent = createApplicationComponent();
    }

    public BusbyBakingComponent createApplicationComponent() {
        return DaggerBusbyBakingComponent.builder()
                .networkModule(new NetworkModule())
                .androidModule(new AndroidModule(BusbyBakingApplication.this))
                .build();
    }

    public BusbyBakingComponent getApplicationComponent() {
        return applicationComponent;
    }

    public RecipeListComponent createRecipeListComponent(MainActivity activity) {
        recipeListComponent = applicationComponent.add(new RecipeListModule(activity));
        return recipeListComponent;
    }

    public void releaseRecipeListComponent() {
        recipeListComponent = null;
    }
}

在我的片段中,这就是我试图注入的方式:

@Inject MainActivity mainActivity;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    ((BusbyBakingApplication)getActivity().getApplication())
            .createRecipeListComponent((MainActivity)getActivity())
            .inject(RecipeListView.this);
}

我一直收到以下错误:

Error:(14, 8) error: [me.androidbox.busbybaking.di.RecipeListComponent.inject(me.androidbox.busbybaking.recipieslist.RecipeListView)] me.androidbox.busbybaking.recipieslist.MainActivity cannot be provided without an @Inject constructor or from an @Provides- or @Produces-annotated method.
me.androidbox.busbybaking.recipieslist.MainActivity is injected at
me.androidbox.busbybaking.recipieslist.RecipeListView.mainActivity
me.androidbox.busbybaking.recipieslist.RecipeListView is injected at
me.androidbox.busbybaking.di.RecipeListComponent.inject(target)

非常感谢任何建议。

2 个答案:

答案 0 :(得分:1)

如果您查看模块

@RecipeListScope
@Provides
public RecipeItemListener providesRecipeListMainActivity() {
    return mainActivity;
}

您提供的界面(很好)而不是MainActivity(实现)。

因为您请求MainActivity

@Inject MainActivity mainActivity;

您收到此错误:

  

无法提供MainActivity [...]

因为您只提供RecipeItemListener

将您的代码从MainActivity中的RecipeListView转换为

@Inject RecipeItemListener recipeListener;

如果您的其他设置正确,它应该可以正常工作。

答案 1 :(得分:0)

您可以使用getActivity()访问Fragment中的活动,并将其转换为您的接口侦听器

memberID        productID   Date            Rating  
A1004AX2J2HXGL  B0007RT9LC  May 30, 2005    3   

更简单,没有任何不必要的注射