Kotlin错误:Dagger不支持注入私人领域

eur*_*com 35 android dependency-injection kotlin dagger dagger-2

我在kotlin活动中使用ViewPager,我希望在Kotlin Fragment中使用匕首注射.我有错误:Dagger不支持注入私有字段.在Java Fragment中匕首注射工作.为什么我不能在kotlin片段中注入匕首?

在我的kotlin活动中

mPagerAdapter = object : FragmentPagerAdapter(supportFragmentManager) {

        private val mFragments = arrayOf(KotlinFragment(), JavaFragment())
        private val mFragmentNames = arrayOf(getString(R.string.cashdocuments), getString(R.string.action_absmysql))

        override fun getItem(position: Int): Fragment {
            return mFragments[position]
        }

        override fun getCount(): Int {
            return mFragments.size
        }

        override fun getPageTitle(position: Int): CharSequence {
            return mFragmentNames[position]
        }
    }
Run Code Online (Sandbox Code Playgroud)

我的kotlin片段

class KotlinFragment : Fragment()  {


@Inject
internal var mSharedPreferences: SharedPreferences? = null

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    (activity.application as SamfantozziApp).dgaeacomponent().inject(this)

}

override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
                          savedInstanceState: Bundle?): View? {
    super.onCreateView(inflater, container, savedInstanceState)
    val rootView = inflater!!.inflate(R.layout.activity_absserver, container, false)

    return rootView
}

}
Run Code Online (Sandbox Code Playgroud)

消息gradle build

在此输入图像描述

azi*_*ian 46

无意中,我遇到了自己的答案,不得不承认,事实上它不起作用(至少对我的用例而言).请考虑Avilio的回答也为我工作:替代internallateinit.


老答案

删除internal修饰符.Dagger至少需要包私有访问才能访问带注释的字段.在Kotlin中,internal修饰符不是 Java的包 - 私有访问修饰符的替代.

有关Java和Kotlin中修饰符之间差异的详细说明,请参阅Fragmented podcast的第101集 - "学习Kotlin - 可见性修饰符,内部修饰符,模块"以及官方文档.


Dan*_*okh 42

你有错误:

    @Inject
internal var mSharedPreferences: SharedPreferences? = null
Run Code Online (Sandbox Code Playgroud)

这看起来像是@InjectKotlinFragment类中添加了注释

请将其更改为此,它将起作用:

var mSharedPreferences: SharedPreferences? = null
        @Inject set
Run Code Online (Sandbox Code Playgroud)

以下是文档的链接:https://kotlinlang.org/docs/reference/annotations.html

  • 你也可以:`@set:注入var mSharedPreferences:SharedPreferences?= null` (3认同)

Avi*_*lio 27

即使删除了内部关键字,我也有同样的错误.所以我用lateinit取代了内部并且它起作用了.

  • 请注意,lateinit 不允许可为 null 类型(? type)。对于可为 null 的字段,请使用 Provider 或 Lazy。包装类型可以为空。 (2认同)

Hem*_*mar 21

很简单,你可以这样做,改变这一行

@Inject
internal var mSharedPreferences: SharedPreferences? = null
Run Code Online (Sandbox Code Playgroud)

@set:Inject
internal var mSharedPreferences: SharedPreferences? = null
Run Code Online (Sandbox Code Playgroud)

这项工作就像我的情况下的魅力.

  • 谢谢!这对我来说可以注入像整数这样的原始类型。 (2认同)
  • 很好。很有魅力。谢谢! (2认同)

0xA*_*iHn 6

@Inject
lateinit var mSharedPreferences: SharedPreferences
Run Code Online (Sandbox Code Playgroud)

此外,这对我也适用于后期初始化变量


小智 6

我遵循了上述建议,不要将该领域设置为内部。但是,这还不够。Kapt 仍然在编译期间将 var 转换为私有。

我不得不添加@JvmField注释以使其表现得更好。

我找到的答案在这里:https : //discuss.kotlinlang.org/t/kapt-converting-public-fields-to-private-during-compilation/11757


shi*_*ang 5

@Inject
internal var mSharedPreferences: SharedPreferences? = null
Run Code Online (Sandbox Code Playgroud)

只需将其更改为

@Inject
lateinit var mSharedPreferences: SharedPreferences
Run Code Online (Sandbox Code Playgroud)

PS 您不能将 Lateinit 与可空值一起使用。