计一次 Dagger2 android kotlin 的坑

dagger2 里 如果@Model 注解的是抽象类时 @provides 标注的必须是静态方法
A @Module may not contain both non-static @Provides methods and abstract @Binds or @Multibinds declarations

java 方式这样写没有问题 而我们知道Kotlin 是没有static 标记显示是静态方法 需要写companion object 来包含静态成员

@Module
public abstract class ApplicationModule{
  
    @Singleton
    @Binds
    abstract   Context provdeeAppContext(Application application);

    @Singleton
    @Provides
    public static String provideString(){
        return "this is test";
    }

}

Kotlin 包含静态成员的 方式

@Module
abstract class ApplicationModule {

    @Singleton
    @Binds
    abstract   fun provdeeAppContext(application: Application): Context
    
    companion object {
        @Singleton
        @Provides
        fun provideString():String="this is test"
    }
}

但是上面还是报一样的错。 下面是Kotlin生成对应的java 可以看出来 Kotlin 里的静态方法其实是生成了一个内部静态类包含

@Module
@Metadata(...)
public abstract class ApplicationModule {
   public static final ApplicationModule.Companion Companion = new ApplicationModule.Companion((DefaultConstructorMarker)null);

   @Singleton
   @Binds
   @NotNull
   public abstract Context provdeeAppContext(@NotNull Application var1);

   @Metadata( ...)
   public static final class Companion {
      @Singleton
      @Provides
      @NotNull
      public final String provideString() {
         return "this is test";
      }

      private Companion() {
      }

      // $FF: synthetic method
      public Companion(DefaultConstructorMarker $constructor_marker) {
         this();
      }
   }
}

不知道这个 dagger2 后期版本会不会修改 暂时能做到的方式就是避免 @Provides 不要写在抽象类里 把@Binds标记的抽象方法 写在另一个类里 然后 再用非抽象类 include 进来 如下

@Module
abstract class ApplicationBindsModule {
    @Singleton
    @Binds
    abstract fun provdeeAppContext(application: Application): Context
}

@Module(includes = arrayOf(ApplicationBindsModule ::class))
class ApplicationProvidesModule {
        @Singleton
        @Provides
        fun provideString(context:Context):String{
          return "this is test ${context.packageName}"
        }
}

或是用Component如下

@Module
abstract class ApplicationBindsModule {
    @Singleton
    @Binds
    abstract fun provdeeAppContext(application: Application): Context
}

@Module
class ApplicationProvidesModule {
        @Singleton
        @Provides
        fun provideString(context:Context):String{
          return "this is test ${context.packageName}"
        }
}


@Component(modules = arrayOf(ApplicationBindsModule::class,ApplicationProvidesModule::class))
public interface AppCompoent:AndroidInjector{
 ...
}

你可能感兴趣的:(计一次 Dagger2 android kotlin 的坑)