美文网首页Android
注解自动生成dagger2 Component组件的工具

注解自动生成dagger2 Component组件的工具

作者: Lightofrain | 来源:发表于2017-07-05 16:48 被阅读179次

    自己通过apt写的一个自动生成Component组件的注解工具,主要具有以下功能:

    • 生成Component组件,可指定一个或多个Module,可指定scope,并可以添加子组件(SubComponent)

    • 生成子组件SubComponent,并可指定Module,scope,父组件和子组件

    • 自动在组件中提供出子组件,并提供inject方法

    • 还能根据生成的组件,生成DaggerHelper帮助类,更方便的注入

    注解种类:

    • GenRootComponent(int tag,int childTag,modules,scope)
      该注解用在哪个类上,就根据该类生成代码
      生成的Component被@Component注解
      参数含义:
      -tag 是自己的标识,tag一致的Component为同一组(主要用于父组件查找子组件,不填默认为0)
      -childTag 是子组件标识,工具会通过该标识来查找所有tag和此标识相等的SubComponent,并在本Component中提供出来
      -modules 该组件对应的Module(必填,一个或多个)
      -scope 该组件对应的scope(选填)
    @GenRootComponent(scope = Singleton.class, modules = {AppModule.class}, tag = 10, childTag = 11)
    public class App extends Application {
    }
    

    生成的代码

    @Component(
        modules = AppModule.class
    )
    @Singleton
    public abstract interface AppComponent extends MembersInjector<App> {
      BaseActivityComponent.Builder providerBaseActivityComponent();
    
      @Component.Builder
      abstract interface Builder {
        AppComponent build();
    
        Builder setModule(AppModule module);
      }
    }
    
    • GenSubComponent(int tag,int childTag,modules,scope)
      该注解用在哪个类上,就根据该类生成代码
      生成的Component被@Subcomponent注解
      生成的Subcomponent依然可以有子组件注解
      参数含义:
      -tag 是自己的标识,tag一致的Component为同一组(主要用于父组件查找子组件,不填默认为0)
      -childTag 是子组件标识,工具会通过该标识来查找所有tag和此标识相等的SubComponent,并在本Component中提供出来
      -modules 该组件对应的Module(必填,一个或多个)
      -scope 该组件对应的scope(选填)
    @GenSubComponent(modules = ActivityModule.class, tag = 12)
    public class MainActivity extends BaseActivity {
    }
    

    生成的代码

    @Subcomponent(
        modules = ActivityModule.class
    )
    public abstract interface MainActivityComponent extends 
    //提供子组件
    MembersInjector<MainActivity> {
      @Subcomponent.Builder
      abstract interface Builder {
        MainActivityComponent build();
    
        Builder setModule(ActivityModule module);
      }
    }
    
    
    • @GenInheritedSubComponent(int tag,int childTag,modules,scope)
      有时可能需要在基类中注入需要的对象,这样的话,每一个该基类的实现类都需要生成Component,并注入该实现类,才能保证基类中的对象不为空,有时并不是每个Activity或Fragment都需要自己的Component,这时就可以用该注解,该注解适合使用在基类中,生成基类的Component,如果某一个实现类不需要Component,就可以使用基类的Component,并且通过该注解生成的Component,会提供所有没有自己的Component的实现类的inject()方法来注入自己(该步骤可在基类中完成)
      其他功能与GenSubComponent一致

    参数含义:
    -tag 是自己的标识,tag一致的Component为同一组(主要用于父组件查找子组件,不填默认为0)
    -childTag 是子组件标识,工具会通过该标识来查找所有tag和此标识相等的SubComponent,并在本Component中提供出来
    -modules 该组件对应的Module(必填,一个或多个)
    -scope 该组件对应的scope(选填)

    @GenInheritedSubComponent(tag = 11, childTag = 12, modules = BaseModule.class, scope = BaseScope.class,shouldInject = false)
    public class BaseActivity extends AppCompatActivity
    

    生成的代码

    @Subcomponent(
        modules = BaseModule.class
    )
    @BaseScope
    public abstract interface BaseActivityComponent {
    //该Activity没有自己的Component,则提供注入方法
      void injectMembers(AppActivity target);
    
      SplashActivityComponent.Builder providerSplashActivityComponent();
    
      MainActivityComponent.Builder providerMainActivityComponent();
    
      @Subcomponent.Builder
      abstract interface Builder {
        BaseActivityComponent build();
    
        Builder setModule(BaseModule module);
      }
    }
    
    • @GenDaggerHelper
      功能

    • 通过该注解,可以生成DaggerHelper辅助类(单例)提供注入方法

    • 该注解可使用在任何一个类上(主要为了提供一个包来存放该辅助类)

    • 生成的注入方法时分层级的,就是说,必须先注入该组件的父组件,才能注入该组件,不然会空指针(因为父组件还没获取到)

    • @GenInheritedSubComponent注解的基类的子类(没有自己的Component的子类)统一提供一个注入方法,会根据传入的类型,自动找到inject()方法来注入(也就是说可以在基类中注入)

    • 生成的注入方法对应的Module构造函数若有参数,则注入时也需要传入对应的参数

    具体来看生产代码

    public class DaggerHelper {
      public AppComponent appcomponent;
    
      private BaseActivityComponent baseactivitycomponent;
    
      private DaggerHelper() {
      }
    
      public static DaggerHelper getInstance() {
        return Holder.INSTANCE;
      }
    
      public AppComponent getAppComponent(App target, Application param0) {
        appcomponent = DaggerAppComponent.builder().setModule(new AppModule(param0)).build();
        appcomponent.injectMembers(target);
        return appcomponent;
      }
    
    //因BaseModule()有参数,所以这里也需要传参(param0)
      public BaseActivityComponent getBaseActivityComponent(Object target, Activity param0) {
        baseactivitycomponent = appcomponent.providerBaseActivityComponent().setModule(new BaseModule(param0)).build();
        if(target instanceof AppActivity) {
          AppActivity appactivity = (AppActivity)target;
          baseactivitycomponent.injectMembers(appactivity);
        }
        return baseactivitycomponent;
      }
    
      public MainActivityComponent getMainActivityComponent(MainActivity target, Activity param0) {
        MainActivityComponent mainactivitycomponent = baseactivitycomponent.providerMainActivityComponent().setModule(new ActivityModule(param0)).build();
        mainactivitycomponent.injectMembers(target);
        return mainactivitycomponent;
      }
    
      public SplashActivityComponent getSplashActivityComponent(SplashActivity target) {
        SplashActivityComponent splashactivitycomponent = baseactivitycomponent.providerSplashActivityComponent().setModule(new SpashModule()).build();
        splashactivitycomponent.injectMembers(target);
        return splashactivitycomponent;
      }
    
      private static class Holder {
        private static final DaggerHelper INSTANCE = new DaggerHelper();
      }
    }
    

    库的介绍就到这里了,希望对大家有所帮助!!!

    下面是项目地址:
    注:项目中还有两个其他的注解工具,以后有时间再介绍

    gradle:

     compile "com.suhang.lazy:lazyannotation_annotation:1.1.8"
     compile "com.suhang.lazy:lazyannotation:1.1.8"
     annotationProcessor "com.suhang.lazy:lazyannotation_compiler:1.1.8"
    

    https://github.com/lightofrain/LazyAnnotation.git

    相关文章

      网友评论

        本文标题:注解自动生成dagger2 Component组件的工具

        本文链接:https://www.haomeiwen.com/subject/tbayfxtx.html