Kotlin已经出来很久了,最近也开始用kotlin开发android应用了,但是在使用kotlin+dagger2开发android应用的时候遇到了一些问题,在这里记录一下,希望能帮到同样遇到这些问题的同学。
先看一下在java下一个简单的dagger2的例子。 1、在app的build.gradle里加入dagger2的库
1 2 compile 'com.google.dagger:dagger:2.15' annotationProcessor 'com.google.dagger:dagger-compiler:2.15'
2、编写一个简单的AppModule和AppComponent
1 2 3 4 5 6 7 8 @Module public class AppModule { @Provides public String provideHelloWorld () { return "Hello World" ; } }
1 2 3 4 5 @Component(modules = AppModule.class) public interface AppComponent { void inject (MainActivity activity) ; }
3、在MainActivity里使用
1 2 3 4 5 6 7 8 9 10 11 12 13 public class MainActivity extends AppCompatActivity { @Inject String helloWorld; @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); DaggerAppComponent.create().inject(this ); Toast.makeText(this , helloWorld, Toast.LENGTH_SHORT).show(); } }
OK,到此一个用java写的简单的dagger2的例子就到此结束了,运行一切正常。 然后我们将这个例子搬到kotlin下看看效果 1、同样在build.gradle里加入dagger2的引用,跟上面一样这里就不多写了 2、编写一个同样的AppModule和AppComponent
1 2 3 4 5 6 7 8 @Module class AppModule { @Provides fun provideHelloWorld () :String{ return "Hello World" } }
1 2 3 4 @Component(modules = [AppModule::class]) interface AppComponent { fun inject (mainActivity: MainActivity) }
上面两步都没有问题,跟java一样只是换成了用Kotlin来写。但是接下来使用DaggerAappComponent
的使用就出问题了,我们知道DaggerAappComponent是dagger根据我们AppComponent类生成的,但是现在DaggerAappComponent这个类并没有生成。
尝试了很多办法各种make、build clean、重启Android Studio、修改Kotlin版本、修改Dagger2版本等等,发现都没有效果,后来才发现原来使用Kotlin的build.gradle的配置不一样,要使用kotlin-kapt插件,要将annotationProcessor换成kapt。如下
1、在app的build.gradle加上kotlin-kapt的插件
1 apply plugin: 'kotlin-kapt'
2、dependencies中dagger2的引用改为
1 2 implementation 'com.google.dagger:dagger:2.15' kapt 'com.google.dagger:dagger-compiler:2.15'
然后重新编译项目,终于生成了DaggerAappComponent
了,然后在MainActivity中使用
1 2 3 4 5 6 7 8 9 10 11 12 class MainActivity : AppCompatActivity() { @Inject var helloWorld:String? = null override fun onCreate (savedInstanceState: Bundle?) { super .onCreate(savedInstanceState) setContentView(R.layout.activity_main) DaggerAppComponent.create().inject(this ) Toast.makeText(this , helloWorld, Toast.LENGTH_SHORT).show() } }
运行。。。然后报错了
1 2 3 4 5 6 7 8 Error:(10 , 2 ) 错误: Dagger does not support injection into private fields private java.lang.String helloWorld; ^ Error:(13 , 2 ) 错误: com.cm.kotlindagger2demo.MainActivity cannot be provided without an @Inject constructor or from an @Provides -annotated method. public abstract void inject (@org .jetbrains.annotations.NotNull() ^ com.cm.kotlindagger2demo.MainActivity is injected at com.cm.kotlindagger2demo.AppComponent.inject(mainActivity)
原来使用dagger2注入时变量要使用关键字lateinit
修饰,顾名思义就是延迟初始化的意思,修改如下:
1 2 @Inject lateinit var helloWorld:String
运行,终于正常了。打完收工!