Kotlin已经出来很久了,最近也开始用kotlin开发android应用了,但是在使用kotlin+dagger2开发android应用的时候遇到了一些问题,在这里记录一下,希望能帮到同样遇到这些问题的同学。
先看一下在java下一个简单的dagger2的例子。
1、在app的build.gradle里加入dagger2的库
implementation 'com.google.dagger:dagger:2.15'
annotationProcessor 'com.google.dagger:dagger-compiler:2.15'
2、编写一个简单的AppModule和AppComponent
@Module
public class AppModule {
@Provides
public String provideHelloWorld(){
return "Hello World";
}
}
@Component(modules = AppModule.class)
public interface AppComponent {
void inject(MainActivity activity);
}
3、在MainActivity里使用
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
@Module
class AppModule {
@Provides
fun provideHelloWorld():String{
return "Hello World"
}
}
@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的插件
apply plugin: 'kotlin-kapt'
2、dependencies中dagger2的引用改为
implementation 'com.google.dagger:dagger:2.15'
kapt 'com.google.dagger:dagger-compiler:2.15'
然后重新编译项目,终于生成了DaggerAappComponent
了,然后在MainActivity中使用
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()
}
}
运行。。。然后报错了
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
修饰,顾名思义就是延迟初始化的意思,修改如下:
@Inject
lateinit var helloWorld:String
运行,终于正常了。打完收工!
个人博客链接