在kotlin中使用dagger2遇到的一個問題

ditclear發表於2017-10-28

寫在前面

最近在使用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語法直接就寫專案的不在少數(雖說確實轉的快),但多看看文件也許這個問題就不存在了

所以還是繼續寫了。見笑了,哈

相關文章