Android - Dagger2 使用和原理

Dagger2从入门到放弃再到恍然大悟

http://www.jianshu.com/p/cd2c1c9f68d4

http://www.jianshu.com/p/39d1df6c877d

http://blog.csdn.net/u012943767/article/details/51897247

 

源码解析:

 

DEMO

不依赖注入:

public class MainActivity extends AppCompatActivity implements MainContract.View {
    private MainPresenter mainPresenter;
    ...

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //实例化presenter 将view传递给presenter
        mainPresenter = new MainPresenter(this);
        //调用Presenter方法加载数据
         mainPresenter.loadData();

         ...
    }

}

public class MainPresenter {
    //MainContract是个接口,View是他的内部接口,这里看做View接口即可
    private MainContract.View mView;

    MainPresenter(MainContract.View view) {
        mView = view;
    }

    public void loadData() {
        //调用model层方法,加载数据
        ...
        //回调方法成功时
        mView.updateUI();
    }

 

依赖注入:

public class MainActivity extends AppCompatActivity implements MainContract.View {
    @Inject
    MainPresenter mainPresenter;
    ...

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

         DaggerMainComponent.builder()
                .mainModule(new MainModule(this))
                .build()
                .inject(this);
        //调用Presenter方法加载数据
         mainPresenter.loadData();

         ...
    }

}

public class MainPresenter {
    //MainContract是个接口,View是他的内部接口,这里看做View接口即可
    private MainContract.View mView;

    @Inject
    MainPresenter(MainContract.View view) {
        mView = view;
    }    
    public void loadData() {
        //调用model层方法,加载数据
        ...
        //回调方法成功时
        mView.updateUI();
    }

@Module
public class MainModule {
    private final MainContract.View mView;

    public MainModule(MainContract.View view) {
        mView = view;
    }

    @Provides
    MainView provideMainView() {
        return mView;
    }
}

@Component(modules = MainModule.class)
public interface MainComponent {
    void inject(MainActivity activity);
}

 

分析

注入的目的就是两个:

1. 让view(Activity)得到 mainPresenter的依赖,可以调用它的方法

2. 让mainPresenter得到view(Activity)的依赖,可以调用它的方法

 

从源码看这两个目的实现

DaggerMainComponent.builder()
                .mainModule(new MainModule(this))
                .build()
                .inject(this);

 

DaggerMainComponent.builder() 方法会实例化一个Build类并返回

Build类

Build类用来管理一个mainModule,并实例化DaggerMainComponent类。

public static final class Builder {
    private MainModule mainModule;

    private Builder() {}

    public MainComponent build() {
      if (mainModule == null) {
        throw new IllegalStateException(MainModule.class.getCanonicalName() + " must be set");
      }
      return new DaggerMainComponent(this);
    }

    public Builder mainModule(MainModule mainModule) {
      this.mainModule = Preconditions.checkNotNull(mainModule);
      return this;
    }
  }

而mainModule负责管理一个view,别的类可以通过他的get()方法得到他管理的view(activity)。

@Module
public class MainModule {
    private final MainContract.View mView;

    public MainModule(MainContract.View view) {
        mView = view;
    }

    @Provides
    MainContract.View provideMainView() {
        return mView;
   }   
}

 

所以这里

DaggerMainComponent.builder()
                .mainModule(new MainModule(this))

就完成了把view(activity)依附到一个mainModule上,再实例化一个Build类管理mainModule,最后用这个Build来实例化DaggerMainComponent

而DaggerMainComponent用来管理三个成员

provideMainViewProvider : 如名字所说,管理着mainview,可以从中得到mainview

mainPresenterProvider: 如名字所说,管理着mainPresenter,可以从中得到mainPresenter

mainActivityMembersInjector:

public final class DaggerMainComponent implements MainComponent {
  private Provider<MainContract.View> provideMainViewProvider;

  private Provider<MainPresenter> mainPresenterProvider;

  private MembersInjector<MainActivity> mainActivityMembersInjector;

  private DaggerMainComponent(Builder builder) {
    assert builder != null;
    initialize(builder);
  }

  public static Builder builder() {
    return new Builder();
  }

  @SuppressWarnings("unchecked")
  private void initialize(final Builder builder) {

    this.provideMainViewProvider = MainModule_ProvideMainViewFactory.create(builder.mainModule);

    this.mainPresenterProvider = MainPresenter_Factory.create(provideMainViewProvider);

    this.mainActivityMembersInjector = MainActivity_MembersInjector.create(mainPresenterProvider);
  }

  @Override
  public void inject(MainActivity activity) {
    mainActivityMembersInjector.injectMembers(activity);
  }

  ...
}

在Build的build()方法中创建了Dagger类的实例,从而调用了它的构造函数

DaggerMainComponent.builder()
                .mainModule(new MainModule(this))
                .build()

Dagger类的init()函数,首先用mainModule实例化了工厂类MainModule_ProvideMainViewFactory

public final class MainModule_ProvideMainViewFactory implements Factory<MainContract.View> {
  private final MainModule module;

  public MainModule_ProvideMainViewFactory(MainModule module) {
    assert module != null;
    this.module = module;
  }

  @Override
  public MainContract.View get() {
    return Preconditions.checkNotNull(
        module.provideMainView(), "Cannot return null from a non-@Nullable @Provides method");
  }

  public static Factory<MainContract.View> create(MainModule module) {
    return new MainModule_ProvideMainViewFactory(module);
  }
}

然后用provideMainViewProvider实例化了MainPresenter_Factory工厂类

public final class MainPresenter_Factory implements Factory<MainPresenter> {
  private final Provider<MainContract.View> viewProvider;

  public MainPresenter_Factory(Provider<MainContract.View> viewProvider) {
    assert viewProvider != null;
    this.viewProvider = viewProvider;
  }

  @Override
  public MainPresenter get() {
    return new MainPresenter(viewProvider.get());
  }

  public static Factory<MainPresenter> create(Provider<MainContract.View> viewProvider) {
    return new MainPresenter_Factory(viewProvider);
  }
}

这个工厂类实例化了MainPresenter并返回,所以可以通过工厂类mainPresenterProvider的get方法得到mainPresenter。

public class MainPresenter {
    MainContract.View mView;
    @Inject
    MainPresenter(MainContract.View view) {
        mView = view;
    }
 }

在实例化

 

最后通过mainPresenterProvider实例化MainActivity_MembersInjector。我们看到这个类前面是MainActivity开头,因此可以想到是MainActivity对应得注入类,我们后面再分析这个类。

public final class MainActivity_MembersInjector implements MembersInjector<MainActivity> {
  private final Provider<MainPresenter> mainPresenterProvider;

  public MainActivity_MembersInjector(Provider<MainPresenter> mainPresenterProvider) {
    assert mainPresenterProvider != null;
    this.mainPresenterProvider = mainPresenterProvider;
  }

  public static MembersInjector<MainActivity> create(
      Provider<MainPresenter> mainPresenterProvider) {
    return new MainActivity_MembersInjector(mainPresenterProvider);
  }

  @Override
  public void injectMembers(MainActivity instance) {
    if (instance == null) {
      throw new NullPointerException("Cannot inject members into a null reference");
    }
    instance.mainPresenter = mainPresenterProvider.get();
  }

  public static void injectMainPresenter(
      MainActivity instance, Provider<MainPresenter> mainPresenterProvider) {
    instance.mainPresenter = mainPresenterProvider.get();
  }
}

MainActivity_MembersInjector类持有一个MainPresenterProvider,从injectMembers方法可以让一个view(activity)得到这个mainPresenter。

另外MainPresenterProvider.get()方法实例化了MainPresenter

  @Override
  public MainPresenter get() {
    return new MainPresenter(viewProvider.get());
  }
public class MainPresenter {
    MainContract.View mView;
    @Inject
    MainPresenter(MainContract.View view) {
        mView = view;
    }
 }

至此MainPresenter就得到了View(Activity)的实例,可以调用它的方法,目的二实现

 

最后看

DaggerMainComponent.builder()
                .mainModule(new MainModule(this))
                .build()
                .inject(this);

调用了Dagger的inject方法

@Override
  public void inject(MainActivity activity) {
    mainActivityMembersInjector.injectMembers(activity);
  }

就是上面的injectMembers方法。至此activity就拿到了mainPresenter的实例,可以调用它的方法

目的一实现。

 

感谢:

http://www.jianshu.com/p/cd2c1c9f68d4

http://alighters.com/blog/2016/04/15/dagger2-indepth-understanding/

http://chriszou.com/2016/05/10/android-unit-testing-di-dagger.html

http://blog.nimbledroid.com/2016/03/07/performance-of-dependency-injection-libraries-zh.html

http://google.github.io/dagger/

 

关于依赖的实现

Dagger2的使用以及源码分析

这篇文章讲的不错,我的理解如下:

整个实现步骤大概是这样的

假设Bus类注入到MainActvitiy

1.编译生成BusProvider类,Injector类,以及一些工厂类

2.Dagger类初始化

调用BusProvider的create()函数得到BusProvider类的实例

如果create里需要busModule的provide参数则create(builder.busModule)

 

再调用Injector的create()得到Injector类实例

3.调用Injector的inject()方法,这个是在component里定义了inject给谁

Injector类持有注入对象的实例,inject(this)时传入的

@Override  
  public void injectMembers(Bus instance) {  
    if (instance == null) {  
      throw new NullPointerException("Cannot inject members into a null reference");  
    }  
    instance.engine = engineProvider.get();  
  }

调用了provider.get()方法

如果是构造函数,provider.get() 实现是 return new Bus();

如果是module,provider.get() 实现是 return module.provide();

  1. @Override  
  2.   public void injectMembers(Bus instance) {  
  3.     if (instance == null) {  
  4.       throw new NullPointerException("Cannot inject members into a null reference");  
  5.     }  
  6.     instance.engine = engineProvider.get();  
  7.   }
posted @ 2017-07-29 01:15  qlky  阅读(1087)  评论(0编辑  收藏  举报