当前位置:  开发笔记 > 编程语言 > 正文

在Android上使用Dagger 2进行懒惰注射

如何解决《在Android上使用Dagger2进行懒惰注射》经验,为你挑选了2个好方法。

我是Dagger 2的新手.我有这个场景,我不想在我的应用程序中注入一个对象(在演示者中,在api中)

我最初没办法提供它.在我的应用程序的某个阶段进行身份验证之后才会创建它.

来自文档http://google.github.io/dagger/

我看到Lazy加载可能是一种解决这个问题的方法,例如

@Inject 
Lazy lazyGrinder;

然后使用以下方法获取这样的值:lazyGrinder.get().grind();

我的问题是:

我可以安全地用新的对象交换对象吗?

有没有其他推荐的方法来做到这一点?

谢谢



1> Jeff Bowman ..:

这不是一个很好的匹配Lazy.Lazy是一种延迟昂贵的对象初始化的好方法,但它暗示了一些你不想要或不需要的语义,特别是关于你想要的"安全交换"行为.

简而言之,Lazy是一个在本地进行memoizes的Provider包装器:

如果你从不打电话get,Dagger永远不会创造有问题的对象.

第一次调用get创建和存储对象实例.

第二次调用get返回相同的实例,依此类推,无论对象是否标记为Singleton.

这使得Lazy成为昂贵对象的绝佳选择,否则该对象将成为一个领域(但可能永远不会被使用).但是,如果引用可能会改变(按照您的意愿),Lazy将会让人感到困惑:它会在第一次使用时存储该值并且永远不会在本地更新,因此多个过时的副本可能会在您的应用程序中浮动什么是"正确的"价值在任何给定的时间.


从您的示例中借用Grinder,更好的解决方案包括:

使用@Provides返回模块中的字段的方法,可以在以后更新.您需要Provider为每个长期存在的对象实例注入,因为仅对Grinder的注入引用不会更新.如果你有很多短命的物体,这仍然是最好的选择.

引用是隐式单例,但没有注释,因为您自己控制实例.Dagger会getGrinder经常调用你的方法.

@Module public class YourModule {
  private Grinder grinder;

  public void setGrinder(Grinder grinder) {
    this.grinder = grinder;
  }

  @Provides public Grinder getGrinder() {
    return grinder;
  }
}

/* elsewhere */
YourModule module = new YourModule();
YourComponent component = DaggerYourComponent.builder()
    .yourModule(module)
    .build();
/* ... */
module.setGrinder(latestAndGreatestGrinder);

正如EpicPandaForce在评论中提到的,创建/绑定一个单独的GrinderHolder,GrinderController或AtomicReference对象,它提供当前实例并允许更新.这样就不可能直接注入Grinder,但是注入获取当前正确Grinder的对象是很容易和明显的.如果您的单个GrinderHolder实现在第一次请求之前不创建Grinder,那么您已经有效地创建了一个Lazy单例.



2> 小智..:

如果在创建组件时无法提供该对象,请不要将其添加到“组件”图中!那就是要求混乱的图形依赖和不一致。对于您正在考虑的问题@Subcomponent,更好的解决方案是一种方法,该方法允许您创建一个新组件,该组件可以继承父组件的依赖关系,还可以添加新组件。这是一个例子:

@Component
interface RegularComponent {
  @AppInstanceId String appInstanceId(); // unique per app install; not related to logging in
  AuthenticatedComponent newAuthenticatedComponent();
}

@Subcomponent
interface AuthenticatedComponent {
  Set friends();
  @AccountId String accountId();
}

在此,@AccountId子组件中的可以使用appInstanceId提供帐户ID(如果需要),因为子组件与其父组件共享依赖项。

如果您需要为子组件的模块提供状态(带有accountId,auth令牌等),请随时将其作为参数传递给@Module并将其存储在private final字段中。您可以在文档中阅读有关如何提供子组件模块的更多信息。

推荐阅读
殉情放开那只小兔子
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有