匕首2注射儿童班

时间:2016-02-23 16:24:04

标签: java android dependency-injection subclass dagger-2

据我所知,对于Dagger 2,我无法注入基类并希望它能够继承到子类。但是为什么我不能在子类中调用注入,除非我明确地为该类提供inject方法?

我尝试按照本文中的示例进行操作:Dagger 2: Even Sharper, Less Square。这个解决方案应该允许我在子类中调用inject,但是当我测试它时,我得到了NullPointerException所有@Inject目标。

public abstract class BaseFragment extends Fragment {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        injectComponent(MyApplication.getComponent());
    }

    protected abstract void injectComponent(AppComponent component);
}

public class MyFragment extends BaseFragment {

    @Inject MyDependency mDependency;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
        mDependency.doSomething(); // NullPointerException
        ...
    }

    ...

    @Override
    public void injectComponent(AppComponent component) {
        component.inject(this);
    }
}

是否有另一种注入每个子类的方法而不为每个类创建一个注入方法?或者这是Dagger 2的唯一工作方式吗?如果是这样的话,我最终会得到一个荒谬的长Component课程。使用每个ActivityFragment或其他各种辅助类的注入方法:

@Singleton @Component(modules = {AppModule.class})
public interface AppComponent {

    void inject(MyClass clazz);

    void inject(MyClass2 clazz);

    ...

    void inject(MyClassN clazz);
}

我更愿意在每个课程中调用component.inject(),而不是与另一个inject方法一起调用。{/ p>

虽然相似,但我不认为我的问题是重复Dagger 2 Activity Injection Not Working。这个问题询问为什么注入不起作用,答案就是:因为Dagger 2有一个强类型关联,你必须为每个类声明一个inject方法。这个问题更多地侧重于围绕样板的方法,同时希望保持强大的类型关联。

1 个答案:

答案 0 :(得分:1)

我在AsymmetricFingerprintDialog示例应用程序中使用了一个漂亮的小技巧,但我不知道我是否完全理解它是如何工作的。该示例使用Dagger的第一次迭代,但快速测试表明它也适用于Dagger 2.

对于每个ID,我添加了一个带有Fragment注释的空构造函数,然后使用@Inject注释在@Inject中获取Fragment的实例}。

Activity
public class MainActivity extends AppCompatActivity {

    @Inject MyFragment mFragment;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        MyApplication.getComponent().inject(this);
        getSupportFragmentManager().beginTransaction
                .replace(R.id.fragment_container, mFragment).commit();
        ...
    }
}

这允许我仅在每个public class MyFragment extends Fragment { @Inject MyDependency mDependency; @Inject public MyFragment() {} @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { mDependency.doSomething(); ... } } 中调用MyApplication.getComponent().inject(this),并且依赖关系也将被注入Activity类。这样,我每个Fragment只需要一个inject方法,而不是每个Activity

Fragment

我很好奇这是如何工作的。从我所看到的它与Dagger无关,相反它似乎使用@Singleton @Component(modules = {AppModule.class}) public interface AppComponent { void inject(MainActivity activity); } 注释用于其预期目的?虽然我是Dagger和JSR-330的新手,但我不确定。

编辑:此方法仅适用于@Inject,或者您自己保存并恢复实例。