Kotlin+Dagger2开发android应用需要注意的那些问题

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

运行,终于正常了。打完收工!
个人博客链接

你可能感兴趣的:(Kotlin+Dagger2开发android应用需要注意的那些问题)