设为首页 加入收藏

TOP

Dagger2 (三) 总结篇(四)
2017-10-12 17:57:42 】 浏览:9159
Tags:Dagger2 总结
ctory) { assert factory != null; this.factory = factory; } @SuppressWarnings("unchecked") // cast only happens when result comes from the factory @Override public T get() { // double-check idiom from EJ2: Item 71 Object result = instance; if (result == UNINITIALIZED) { synchronized (this) { result = instance; if (result == UNINITIALIZED) { instance = result = factory.get(); } } } return (T) result; } /** Returns a new scoped provider for the given factory. */ public static <T> Provider<T> create(Factory<T> factory) { if (factory == null) { throw new NullPointerException(); } return new ScopedProvider<T>(factory); } }

我们看下源码,这里的create是创建了一个ScopeProvider的对象,并将工厂传入,当这个ScopeProvider去get的时候,内部有个单例来维持这个对象,这就是为什么我们自定义注解是个单例的秘密。

接下来看看神器的注解是怎么起作用的。

public final class BaseActivity_MembersInjector implements MembersInjector<BaseActivity> {
    private final MembersInjector<FragmentActivity> supertypeInjector;
    private final Provider<Context> contextProvider;

    public BaseActivity_MembersInjector(MembersInjector<FragmentActivity> supertypeInjector, Provider<Context> contextProvider) {
        assert supertypeInjector != null;

        this.supertypeInjector = supertypeInjector;

        assert contextProvider != null;

        this.contextProvider = contextProvider;
    }

    public void injectMembers(BaseActivity instance) {
        if(instance == null) {
            throw new NullPointerException("Cannot inject members into a null reference");
        } else {
            this.supertypeInjector.injectMembers(instance);
            instance.context = (Context)this.contextProvider.get();
        }
    }

    public static MembersInjector<BaseActivity> create(MembersInjector<FragmentActivity> supertypeInjector, Provider<Context> contextProvider) {
        return new BaseActivity_MembersInjector(supertypeInjector, contextProvider);
    }
}

在我们注入这个对象后,injectMembers方法中,写明了BaseActivity中的context对象是从ContextProvider的get方法中得到,根据代码也可以看到,这部分依赖是从ApplicationComponent中的provideContext方法取得。

再看看Lazy Load:

public final class DoubleCheckLazy<T> implements Lazy<T> {
  private static final Object UNINITIALIZED = new Object();

  private final Provider<T> provider;
  private volatile Object instance = UNINITIALIZED;

  private DoubleCheckLazy(Provider<T> provider) {
    assert provider != null;
    this.provider = provider;
  }

  @SuppressWarnings("unchecked") // cast only happens when result comes from the factory
  @Override
  public T get() {
    // to suppress it.
    Object result = instance;
    if (result == UNINITIALIZED) {
      synchronized (this) {
        result = instance;
        if (result == UNINITIALIZED) {
          instance = result = provider.get();
        }
      }
    }
    return (T) result;
  }

  public static <T> Lazy<T> create(Provider<T> provider) {
    if (provider == null) {
      throw new NullPointerException();
    }
    return new DoubleCheckLazy<T>(provider);
  }
}

toasterLazy加载的时候是使用DoubleCheckLazy.create(this.toasterLazyProvider)来进行初始化。而内部是个单例,只有在get时才会初始化。

至此,Dagger2的主要源码就差不多理解了。

二.使用分析

Dagger2很优雅,优雅到你可以特别轻松的调试它,以为他和你手写的代码几乎一模一样,又优雅到几乎所有的错误都从编译器暴露出。

与RoboGuice的反射不同,生成代码必然会导致方法数的增加。但是,我们可以看到生成的代码数量并不多,而且在实际应用过程中也可以看出,确实影响不大,这个可以大家在以后的使用中慢慢体会。

性能上Dagger2会优于RoboGuice,尤其是天生支持懒加载,但是在易用性上,RoboGuice更容易上手和理解,并且针对Android做了很多通用依赖,为项目开发

首页 上一页 1 2 3 4 下一页 尾页 4/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇一款面试复习应用源码 下一篇27个漂亮的移动端注册/登录界面设..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目