在Android上使用Dagger 2进行惰性注入 [英] Lazy Injection with Dagger 2 on Android

查看:131
本文介绍了在Android上使用Dagger 2进行惰性注入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Dagger 2的新手.在这种情况下,我不会在应用程序中插入对象(在演示者中,在api中)

I’m new to Dagger 2. I have this scenario, I wan't to inject an object across my app (in presenters, in api)

我最初没有办法提供它.直到在我的应用程序中进行某些阶段的身份验证后,它才会创建.

I do not have a way to provide it initially. It is not created till after authentication at some stage in my app.

从文档 http://google.github.io/dagger/

我看到延迟加载可能是解决此问题的一种方法,例如

I see Lazy loading might be a way to solve this e.g

@Inject 
Lazy<Grinder> lazyGrinder;

,然后使用以下命令获取类似的值: lazyGrinder.get().grind();

and then get the value like this using: lazyGrinder.get().grind();

我的问题是:

My questions are:

  • 此后我可以安全地用新对象交换对象吗?
  • 还有其他推荐的方法吗?

谢谢

推荐答案

这与Lazy不太匹配. Lazy是延迟昂贵的对象初始化的好方法,但是它暗含了一些您不需要或不需要的语义,尤其是有关您想要的安全交换"行为.

This isn't a good match for Lazy. Lazy is a great way to delay expensive object initialization, but it implies some semantics that you don't want or need, particularly regarding the "safely swap" behavior you want.

简单地说,Lazy是提供程序包装,它在本地进行存储:

To put it simply, Lazy is a Provider wrapper that memoizes locally:

  • 如果您从不调用get,则Dagger绝不会创建有问题的对象.
  • 第一次调用get会创建并存储对象实例.
  • get的第二次调用将返回相同的实例,依此类推,直到永远,无论该对象是否被标记为Singleton.
  • If you never call get, Dagger never creates the object in question.
  • The first call to get creates and stores the object instance.
  • The second call to get returns the same instance, and so on forever, regardless of whether the object was marked as Singleton.

这使得Lazy成为昂贵对象的绝佳选择,否则该对象将成为字段(但可能永远不会使用).但是,如果引用可能会发生变化(随您的意愿),Lazy只会使您感到困惑:它将在初次使用时存储值,并且永远不会在本地进行更新,因此无论您的应用程序中有多少个过时的副本都可能会浮动在任何给定时间的正确"值是什么.

This makes Lazy an excellent choice for an expensive object that would otherwise be a field (but may never be used). However, if the reference is likely to change (as your will), Lazy will simply be confusing: It will store the value at first use and never locally update, so multiple out-of-date copies might be floating around in your application regardless of what the "right" value is at any given time.

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

To borrow the use of Grinder from your example, better solutions include:

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

  • Using a @Provides method that returns a field in a Module, which can be updated later. You'll need to inject Provider<Grinder> for every long-lived object instance, because injected references to Grinder alone won't update. This still might be the best bet if you have a lot of short-lived objects.

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

The reference is implicitly singleton, but is not annotated as such, because you're controlling the instance yourself. Dagger will call your getGrinder method frequently.

@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,但是注入容易获取的对象显然是显而易见的.如果您的单例GrinderHolder实现直到您第一次请求时才创建Grinder,那么您已经有效地自行创建了一个懒惰的单例.

  • As EpicPandaForce mentioned in the comments, create/bind a singleton GrinderHolder, GrinderController, or AtomicReference object that provides the current instance and allows for updating. That way it's impossible to inject a Grinder directly, but easy and obvious to inject the object that fetches the current correct Grinder. If your singleton GrinderHolder implementation doesn't create the Grinder until the first time you ask for it, then you have effectively created a Lazy singleton on your own.

    这篇关于在Android上使用Dagger 2进行惰性注入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆