如何在dagger 2.10

时间:2017-03-28 18:32:37

标签: android dagger-2

我正在尝试将公司应用迁移到dagger 2.10和AndroidInjector.inject方法,但我认为我发现了一个问题。该应用程序使用自定义范围...就像功能登录有3个活动(每个活动都有自己的匕首模块)和一个LoginModule负责共享只应该在此范围内的单身人士。因此,我在第一个Activity中执行了类似的操作:

public class LoginActivity extends AppCompatActivity{
public void onCreate(Bundle bla){
LoginActivityComponent activityComponent = ((CustomApplication) getApplicationContext())
                .plus(new LoginModule()) // generates LoginComponent and save the reference in the CustomApplication
                .plus(new LoginActivityModule(this));
        activityComponent.inject(this);
      ...
}

在其他活动中,我只执行((CustomApplication) getApplicationContext()).getLoginComponent().plus(new ForgetPasswordModule()).inject(this)

如何在使用AndroidInjector时归档相同的行为?

1 个答案:

答案 0 :(得分:5)

单子组件作弊

而不是应用程序中的正常实现:

public class YourApplication extends Application implements HasActivityInjector {
  @Inject DispatchingAndroidInjector<Activity> dispatchingActivityInjector;

  @Override
  public AndroidInjector<Activity> activityInjector() {
    return dispatchingActivityInjector;  // Always get it from Multibindings.
  }
}

只需将活动绑定模块移动到LoginComponent,然后从LoginComponent委托给DispatchingAndroidInjector<Activity>

@Override
public AndroidInjector<Activity> activityInjector() {
  return getOrCreateLoginComponent().getActivityInjector();
}

这是持续维护的最少量,但它看起来相当落后,因为您预先创建了LoginComponent。但是,如果LoginComponent很便宜并且是这种风格的唯一子组件,那么一切都运行良好:LoginComponent的注入器可以在其父节点中看到多重绑定,因此LoginComponent的ActivityInjector将始终工作,即使对于父节点中的绑定也是如此

由于非登录活动的绑定仍驻留在ApplicationComponent中,因此这些活动无法使用父组件的绑定。否则,这等于将您的LoginComponent合并到您的ApplicationComponent中,这可能不是一个选项,否则您就是这样做的。

委派AndroidInjector

如果您的LoginComponent创建起来很昂贵,那么您可以将getOrCreateLoginComponent()调用置于instanceof支票之后移动:

@Inject DispatchingAndroidInjector<Activity> dispatchingActivityInjector;

@Override
public AndroidInjector<Activity> activityInjector() {
  return new AndroidInjector<Activity>() {
    @Override public void inject(Activity activity) {
      if (Activity instanceof LoginActivity
          || Activity instanceof OtherLoginActivity) {
        getOrCreateLoginComponent().getActivityInjector().inject(activity);
      } else {
        // You can chain other subcomponents here as well.
        dispatchingActivityInjector.inject(activity);
      }
    }
  };
}

这意味着您需要保留LoginComponent可以处理的活动的单独列表(可能是LoginComponent或LoginModule中的字段),但是如果您希望避免实例化LoginComponent,直到您确定自己为&#39 ;重新注入与登录相关的活动,这是您如何检查它。上述方法也可以很好地扩展到多个子组件,因为您始终只从一个组件inject上调用DispatchingAndroidInjector<Activity>

混合替代

因为Map存在检查可能非常快,所以您还可以通过先将主注入器检查到将它放入登录组件之前来避免该额外列表。当然,如果你有这种风格的多个子组件,那就开始变得丑陋了。

@Inject DispatchingAndroidInjector<Activity> dispatchingActivityInjector;

@Override
public AndroidInjector<Activity> activityInjector() {
  return new AndroidInjector<Activity>() {
    @Override public void inject(Activity activity) {
      if (!dispatchingActivityInjector.maybeInject(activity)) {
        // It's not in the top level. Start checking subcomponents.
        getOrCreateLoginComponent().getActivityInjector().inject(activity);
      }
    }
  };
}

希望在这三者之间,你不会在这里找到Android注入"worse than pain from any disease or wound known in the universe"