我正在尝试将公司应用程序迁移到Dagger2.10和AndroidInjector.inject方法,但我想我发现了一个问题。应用程序使用自定义作用域…就像功能登录有3个活动(每个活动都有自己的匕首模块)和一个login module,负责共享仅应存在于此作用域中的单例。因此,在第一个活动中,我经常执行如下操作:

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)
我怎么能存档相同的行为时,使用雄激素注射?

最佳答案

单个子组件欺骗
而不是应用程序中的正常实现:

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的injector可以看到其父级中的多绑定,因此logincomponent的activityinjector即使对于父级中的绑定也始终有效。
由于非登录活动的绑定仍位于applicationcomponent中,因此这些活动将无法使用来自父组件的绑定。不过,否则,这就相当于将logincomponent合并到applicationcomponent中,这可能不是一个选项,否则您就会这样做。
雄激素受体
如果您的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或loginmodule中的字段),logincomponent可以处理这些活动,但是如果您想避免实例化logincomponent,直到您确定您正在注入一个与登录相关的活动,下面是检查它的方法。上面的方法也可以很好地扩展到多个子组件,因为您总是从一个组件调用一个inject
混合替代品
因为map presence检查可能非常快,所以您也可以通过在将其抛出到login组件之前先检查主注入器来避免额外的列表。当然,如果你有多个这种风格的子组件,那就开始变得难看了。
@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"

10-01 15:03