在kotlin中使用dagger2遇到的一个问题

1,216 阅读3分钟

写在前面

最近在使用kotlin和Dagger2来开发项目。需要在dagger2 的module返回两个相同的对象,因此使用到@Named注解。

如下图所示

    @Provides
    @Named(Constants.Qualifier_HOME)
    fun provideHomePagerAdapter(): FragmentStatePagerAdapter {

        return object : AbstractPagerAdapter(fragment.childFragmentManager, arrayOf("android","ios")) {
            override fun getItem(pos: Int): Fragment? {
                //...省略
                return list[pos]
            }
        }
    }

    @Provides
    @Named(Constants.Qualifier_COLLECT)
    fun provideCollectPagerAdapter(): FragmentStatePagerAdapter {
        return object : AbstractPagerAdapter(fragment.childFragmentManager, arrayOf("code","article")) {
            override fun getItem(pos: Int): Fragment? {
                //...省略
                return list[pos]
            }
        }
    }

然后各自的页面里

@FragmentScope
class HomeFragment : BaseFragment<ViewPagerFragmentBinding>() {

    @Inject
    @Named("home")
    lateinit var adapter: FragmentStatePagerAdapter
    //...省略
}

@FragmentScope
class MyCollectFragment : BaseFragment<ViewPagerFragmentBinding>() {

    @Inject
    @Named("collect")
    lateinit var adapter: FragmentStatePagerAdapter
    //...省略
}

照理说这样是没问题的(嗯,java代码是这样)

但是却遇到了编译上的问题


然后看控制台输出的error

//...
xxadapter cannot be provided without an @Provides- or @Produces-annotated method.
//...

猜想

哪里不对,猜想可能是@Named注解的问题,于是把@Named去掉,只保留一个provideHomePagerAdapter方法,发现可以运行,不报错了。

解决

看来确实问题在这里,猜想难道是@Named注解在kotlin上有问题

  1. 尝试去自定义了一个Qualifier用来替代@Named,嗯当然还是不行🚫
  2. 然后想想网上是不是有会遇到同样问题的额,结果大多数都在讲dagger2集成使用说明什么的,都是些常规的用法。🚫
  3. 搜了下Stack Overflow 没有找到,然后在dagger2的issue里搜了下@Named,没找到😎(盲人)🚫
  4. 在kotlin交流群里问了,零星的几个人回答,没效果就没声音了。还是要靠自己。🚫
  5. 于是在github上查看了许多使用Dagger2和kotlin开发的项目,结果都是比较常规的用法,或者各自页面有自己的component和module,写成@Named注解的还没看到。

难道kotlin有这么大的缺陷吗??不应该啊!难道是我代码有问题。

然后创建了一个java Demo 项目,使用Dagger2进行了@Named尝试 ------> pass✅

6 . 于是就先放着吧,不用@Named ,先在fragment里用了by lazy 来实例化。——>pass ✅

现在项目开发的差不多了,回过头再来处理它了。

7 . 首先当然还是百度,google,没答案就准备去github 的dagger2项目看看,在issue里搜了一下kotlin

没什么相关的问题,倒是看到了一个问题

然后看到了这样的写法

嗯🤔好像有点不一样,难道要这么写?
这个@field是什么,看过@JvmName @jvmfield 没见过这一个,那就看下文档:地址

🤔🤔🤔,试了试———>pass ✅😊

结语

在写本文时,我又搜了下dagger2的issue,这次搜的是kotlin,然后在closed的问题里看到了

然后大神回答了这个问题

😂
本来想删了不发,但是写本文的初衷

一来是想分享一下这个问题的答案,避免有更多的人踩坑

二来想分享一下自己踩坑时解决的思路和方法(如果够运的话,第三步就应该解决了)

三来是觉得多看看文档是有好处的,想来如我这样看了一下kotlin语法直接就写项目的不在少数(虽说确实转的快),但多看看文档也许这个问题就不存在了

所以还是继续写了。见笑了,哈