Dagger使用自定义Score和组件依赖

知识点:

  • 如何使用自定义Score
  • 使用自定义Score实现全局单例
  • Component(组件)与Component(组件)之间如何进行依赖

问题:

  • 为什么使用Score?
    使用@Singleton经常会报错,语法规则也很多,我们可以使用 @Score来解决这个问题,Score意为作用域。
  • Component(组件)与Component(组件)之间为什么需要依赖?
    意味同一个Activity或者类中不能注入多个Component,所以需要进行依赖。

dependencies组件依赖需要注意:

  • 多个组件之间的scope不能相同,比如MyComponent这个类用的是@APPScore,那PresenterComponet就不能使用@APPScore,可以使用其他的,比如@UserScore
  • 有着依赖的两个Comonent不能都拥有单例,可以其中一个拥有单例,否则会报错。
  • 没有scope的不能依赖有scope的组件 这个类有score,PresenterComponent没有,也是可以的,如果都有也是可以。

需要用到的相关的类
对象类:HttpObject,DatabaseObject,Presenter
Module类:HttpModule,DatabaseModule,PresenterModule
Component(组件):MyComponent,PresenterComponent
自定义Score:AppScore
MyApplication:控制MyComponent

先来看对象类
HttpObject.java

public class HttpObject {
}

DatabaseObject.java

public class DatabaseObject {
}

Presenter.java

public class Presenter {
}

再来看Module类
HttpModule.java

@AppScore
@Module
public class HttpModule{
    @AppScore
    @Provides
    public HttpObject provederHttpObject(){
        return new HttpObject();
    }
}

自定义Score需要在相关的用@Module修饰的类上面加上@AppScore,同时也要在用@Provides修饰的方法上面加上@AppScore,最后要在这个Module相关联的Component上面加上 @AppScore,下面就会看到。

DatabaseModule.java

@Module
public class DatabaseModule {
    @Provides
    public DatabaseObject providerDatabaseObject(){
        return new DatabaseObject();
    }
}

PresenterModule.java

@Module
public class PresenterModule {
    @Provides
    public Presenter providePresenter(){
        return new Presenter();
    }
}

相关的Component
MyComponent.java

@AppScore
@Component(modules = {HttpModule.class,DatabaseModule.class}
,dependencies = PresenterComponent.class)
public interface MyComponent {//这个类会自动生成DaggerMyComponent,在Activity或者其它类中注入的时候使用DaggerMyComponent
    void injectMainActivity(MainActivity mainActivity);
    void injectSecondActivity(SecondActivity secondActivity);
}

自定义Score要在这个Component上面加上@AppScore,dependencies = PresenterComponent.class表示MyComponent依赖PresenterComponent这个Component。

PresenterComponent.java

@Component(modules = PresenterModule.class)
public interface PresenterComponent {
//    void injuctMainActivity(MainActivity mainActivity);
    //依赖的时候不再使用上面的注入,只负责一个对象的提供
    public Presenter provedePresenter();
}

PresenterComponent 这个Component是被MyComponent依赖的Component,如果是这种依赖的话,那我们就不需要使用void injuctMainActivity(MainActivity mainActivity);来进行注入了,只需要提供public Presenter provedePresenter();就可以。

MyApplication.java

public class MyApplication extends Application {
    private MyComponent myComponent;
    @Override
    public void onCreate() {
        super.onCreate();
        myComponent= DaggerMyComponent.builder()
                .httpModule(new HttpModule())
                .presenterComponent(DaggerPresenterComponent.create())
                .build();
    }
    public MyComponent getAppComponent(){
        return myComponent;
    }
}

依赖的时候所有的工作做完之后,那在注入Actiivity或者其他类的时候需要加上这一句presenterComponent(DaggerPresenterComponent.create())

MainActivity.java

public class MainActivity extends AppCompatActivity {
    @Inject
    HttpObject httpObject1;
    @Inject
    HttpObject httpObject2;
    @Inject
    DatabaseObject databaseObject1;
    @Inject
    DatabaseObject databaseObject2;
    @Inject
    Presenter presenter;

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

        ((MyApplication)getApplication()).getAppComponent().injectMainActivity(this);

        Log.i("log",httpObject1.hashCode()+"");//505848839
        Log.i("log",httpObject2.hashCode()+"");//505848839
        Log.i("log",databaseObject1.hashCode()+"");//14166324
        Log.i("log",databaseObject2.hashCode()+"");//104058659
        Log.i("log",presenter.hashCode()+"");//181375837
    }

    public void jump(View view) {
        this.startActivity(new Intent(this,SecondActivity.class));
    }
}

此时可以看到使用自定义Score实现了全局单例。

你可能感兴趣的:(Dagger使用自定义Score和组件依赖)