如何使用 Dagger2 将 Activity 注入片段

How to inject a Activity into a Fragment using Dagger2

我正在尝试将我的 MainActivity 注入片段。我有一个在我的 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);
}

我的申请class

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)

非常感谢您的任何建议。

您可以使用 getActivity() 在 Fragment 中访问 activity 并像这样将其投射到您的界面侦听器

((RecipeItemListener)getActivity()).doSomethingOnListener()

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

如果你看看你的模块

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

您提供接口(这很好)而不是 MainActivity(实现)。

既然你要求了MainActivity

@Inject MainActivity mainActivity;

您收到此错误:

MainActivity cannot be provided [...]

因为你只提供RecipeItemListener.


将您的代码从要求 RecipeListView 中的 MainActivity 更改为

@Inject RecipeItemListener recipeListener;

如果其余设置正确,它应该可以工作。