Dagger 2 - 如何仅注入基础活动/片段

时间:2015-11-04 18:30:34

标签: android dependency-injection dagger-2

我正在从许多来源学习匕首2,例如:http://fernandocejas.com/2015/04/11/tasting-dagger-2-on-android/ 但我仍然没有找到我的问题的答案。

我处理相当复杂的应用程序,包含数十个片段和几个我想要使用DI(匕首2)的活动。对于所有这些片段和活动,我有一个BaseActivity和一个BaseFragment。但是,就我阅读和尝试而言,为了在我的说法中使用@Inject说MainActivity,我必须在Component接口中指定它,并在onCreate方法中调用getApplicationComponent()。inject(this)。当我仅针对BaseActivity执行此操作时,永远不会注入MainActivity中的@Inject注释字段。更糟糕的是,在执行代码的特定部分并抛出NPE之前,我没有发现这一点。

到目前为止,这对我来说是一个交易破坏者,因为这可能是许多崩溃的根源。我需要在Component接口中指定数十个片段和活动,不要忘记在每个onCreate方法中调用inject。

我很高兴听到任何解决方案,因为我真的想使用DI ..

代码示例:

@Singleton
@Component(modules = ApplicationModule.class)
public interface ApplicationComponent {
    void inject(BaseActivity baseActivity);
    Analytics analytics();
}

public class BaseActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.getApplicationComponent().inject(this);
    }
}

public class MainActivity extends BaseActivity {
    @Inject
    Analytics analytics;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        analytics.log("event1"); // THROWS NPE!
    }
}

2 个答案:

答案 0 :(得分:3)

你可以通过注入super来在你的子类中注入属性(因为dagger2在编译时工作,并且没有办法动态检查子类的注释属性。)

你可以将analytics移到超级,然后将它注入那里。要在子类中注入带注释的字段,您必须再次调用注入。

您可以在基类中创建一个抽象方法,例如inject(App app)您只需处理注射。这样你就不会错过'它

如官方documentation所述:

  

虽然类型的成员注入方法将接受其子类型的实例,但只会注入参数类型的注入注释成员及其超类型;亚型成员不会。

答案 1 :(得分:0)

移动

  

@注入       分析分析;

到您的BaseActivity类,Analytics对象在超类中初始化,并由子类自动继承,因此您将不再为null。

 public class MainActivity extends BaseActivity {
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         analytics.log("event1");
     } }