画布 1
dagger2
  IOC
    IOC（Inversion of Control）
是原来由程序代码中主动获取的资源，转变由第三方获取并使原来的代码被动接收的方式，以达到解耦的效果，称为控制反转
    不用注入技术的代码
  基本配置
    implementation 'com.google.dagger:dagger:2.4'
annotationProcessor 'com.google.dagger:dagger-compiler:2.4'
  使用逻辑
    module:用于提供对象
component:用于组织module并进行注入
  基本使用
    1.提供用于注入的对象
      public class HttpObject {
}
    2.编写Module
      /**
* 用来提供对象
*/
@Module
public class HttpModule {
@Provides
public HttpObject providerHttpObject(){
//以后需要网络访问对象，都在这里提供
return new HttpObject();
}
}
    3.编写Component
      @Component(modules = {HttpModule.class})
public interface MyComponent {
//不能用多态
void injectMainActivity(MainActivity mainActivity);
void injectSecActivity(SecActivity secActivity);
}
    4.注入到Activity
      public class MainActivity extends AppCompatActivity {
@Inject
HttpObject httpObject;
@Inject
HttpObject httpObject2;
    5.rebuild项目让APT生成需要的文件
    6.在需要注入的类中使用
      @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//1.语法1
DaggerMyComponent.create().injectMainActivity(this);
//2.语法2
DaggerMyComponent.builder()
.httpModule(new HttpModule())
.databaseModule(new DatabaseModule())
.build()
.injectMainActivity(this);
  单例使用
    @Singleton
@Module
public class HttpModule {
@Singleton
@Provides
public HttpObject providerHttpObject(){
//以后需要网络访问对象，都在这里提供
return new HttpObject();
}
public HttpModule() {
}
}
    @Singleton
@Component(modules = {HttpModule.class, DatabaseModule.class}
,dependencies = {PresenterComponent.class})
public interface MyComponent {
//不能用多态
void injectMainActivity(MainActivity mainActivity);
void injectSecActivity(SecActivity secActivity);
}
    注意：以上单例只能在注入类中局部有效
  全局单例
    public class MyApplication extends Application {
private MyComponent myComponent;
@Override
public void onCreate() {
super.onCreate();
myComponent = DaggerMyComponent.builder()
.httpModule(new HttpModule())
.databaseModule(new DatabaseModule())
.build();
}
public MyComponent getAppComponent(){
return myComponent;
}
}
  多个Component组合依赖
    dagger2不能使用多个Component同时注入同一个类中
这种情况需要进行Component的组合
    dependencies用法
      1.为每个Component定义自己的Scope
        @Scope
@Documented
@Retention(RUNTIME)
public @interface AppScope {
}
        @Scope
@Documented
@Retention(RUNTIME)
public @interface UserScope {
}
      2.进行依赖
        @UserScope
@Component(modules = {PresenterModule.class})
public interface PresenterComponent {
public Presenter providePresenter();
}
        @AppScope
@Component(modules = {HttpModule.class, DatabaseModule.class}
,dependencies = {PresenterComponent.class})
public interface MyComponent {
//不能用多态
void injectMainActivity(MainActivity mainActivity);
void injectSecActivity(SecActivity secActivity);
}
      3.初始化使用
        DaggerMyComponent.builder()
.httpModule(new HttpModule())
.databaseModule(new DatabaseModule())
.presenterComponent(DaggerPresenterComponent.create())
.build();
      dependencies注意事项
        scope&dependencies的使用
1.多个component上面的scope不能相同
2.没有scope的组件不能去依赖有scope的组件
    @Subcomponent用法
      @Subcomponent(modules = {TestSubModule.class})
public interface TestSubComponent {
void injectMainActivity(MainActivity activity);
}
      @Component(modules = {MainModule.class})
public interface MainComponent {
TestSubComponent getTestSubComponent();
}
      DaggerMainComponent.create()
.getTestSubComponent()
.injectMainActivity(this);
  其它用法
    带参数module
      @Module
public class MainModule {
/***
* 构造方法需要其他参数时候
*
* @return
*/
@Provides
B providerB() {
return new B();
}
@Provides
A providerA(B b) {
return new A(b);
}
}
    @Named使用
      module中：
@Named("key1")
@Provides
public User provideUser(){
return new User("jett","123")；
}
@Named("key2")
@Provides
public User provideUser2(){
return new User("jett2","456")；
}
      注入点：
@Named("key1")
@Inject
User user1;
@Named("key2")
@Inject
User user2;
      通过以上语法，就可以实现两个不同的key注入不一样的同类型对象
    lazy 和 Provider
      这种方式是在get的时候，才初始化需要注入的对象
      @Inject
Lazy<A> lazy;
@Inject
Provider<A> provider;
      Log.i("jett",lazy.get().hashCode()+"");
Log.i("jett",provider.get().hashCode()+"");