【问题标题】:How to inject a Activity into a Fragment using Dagger2如何使用 Dagger2 将 Activity 注入 Fragment
【发布时间】:2017-06-09 18:49:00
【问题描述】:

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

我已尝试执行以下操作,但未能成功。只显示代码 sn-ps。

界面

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)

非常感谢您的任何建议。

【问题讨论】:

  • 您不是已经使用getActivity() 获得了片段中的活动吗?

标签: android dagger-2 dagger


【解决方案1】:

如果你看看你的模块

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

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

既然你要求MainActivity

@Inject MainActivity mainActivity;

您收到此错误:

无法提供 MainActivity [...]

因为你只提供RecipeItemListener


将您的代码从需要 MainActivity in RecipeListView 切换为

@Inject RecipeItemListener recipeListener;

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

【讨论】:

  • 该修复有效。我想注入的原因是我想调用 MainActivity 中的方法,该方法从 Activity 托管的片段中实现接口。我想我可以将 Activity 传递给 onAttach 方法中的片段。但是,我认为注入是更好的方法。
【解决方案2】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多