Leanback Presenter 中的 Hilt 注入

Hrk*_*Hrk 5 android dependency-injection dagger-hilt

我对 Hilt 注射还很陌生。我开始将我的整个项目迁移到 DI。

它几乎在任何地方都适用,但当涉及到后仰演示者时,我遇到了一个问题。我不知道这是否与后倾的东西有关或只是希尔特

class LiveShowCardPresenter constructor(context: Context, listener: ShowCardViewListener, val hasVariableWidth: Boolean = false) : ShowCardPresenter(context, listener) {
    override fun onCreateViewHolder(parent: ViewGroup): ViewHolder {
        val viewholder = ViewHolder(LiveShowCardView(context, hasVariableWidth))
        viewholder.prepareViewHolderForeground(context, settings.isATV)
        return viewholder
    }
...
}
Run Code Online (Sandbox Code Playgroud)
abstract class ShowCardPresenter constructor(val context: Context, var listener: ShowCardViewListener?) : Presenter() {
    @Inject lateinit var detailsRepository: DetailsRepository
    @Inject lateinit var settings: BackendSettings
... }
Run Code Online (Sandbox Code Playgroud)
@Singleton
class BackendSettings @Inject constructor(@ApplicationContext val context: Context) {
    val isATV = true // TODO
Run Code Online (Sandbox Code Playgroud)

出现以下错误

    kotlin.UninitializedPropertyAccessException: lateinit property settings has not been initialized
    at ch.netplus.tv.ui.presenters.ShowCardPresenter.getSettings(ShowCardPresenter.kt:43)
    at ch.netplus.tv.ui.presenters.LiveShowCardPresenter.onCreateViewHolder(LiveShowCardPresenter.kt:23)
Run Code Online (Sandbox Code Playgroud)

这意味着当调用 settings.isATV 时它会崩溃,因为当时“settings”变量尚未初始化。我应该怎样做才能按时完成注射?

谢谢 !

Ven*_*min 1

如何将依赖项注入到LiveShowCardPresenter

由于您的抽象类(ShowCardPresenter)执行字段注入,因此您在创建时需要以某种方式注入这些字段LiveShowCardPresenterLiveShowCardPresenter要执行这些注射,您还需要注射。所以,它看起来是这样的:

class LiveShowCardPresenter @Inject constructor(context: Context) : ShowCardPresenter(context) {
    var hasVariableWidth: Boolean = false

    override fun onCreateViewHolder(parent: ViewGroup): ViewHolder {
        val viewholder = ViewHolder(LiveShowCardView(context, hasVariableWidth))
        viewholder.prepareViewHolderForeground(context, settings.isATV)
        return viewholder
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)
abstract class ShowCardPresenter constructor(val context: Context) : Presenter() {
    var listener: ShowCardViewListener? = null

    @Inject lateinit var detailsRepository: DetailsRepository
    @Inject lateinit var settings: BackendSettings
... }
Run Code Online (Sandbox Code Playgroud)

你的片段.kt

@AndroidEntryPoint
class YourFragment: BrowseFragment() {
    @Inject
    lateinit var liveShowCardPresenterProvider: Provider<LiveShowCardPresenter>

    ...
    private void setupUIElements() {
        ...
        //new header
        setHeaderPresenterSelector(object : PresenterSelector() {
            override fun getPresenter(o: Any): Presenter {
                // Everytime when [liveShowCardPresenterProvider.get()] is called - new instance will be created
                val presenter = liveShowCardPresenterProvider.get().apply {
                    // You can set your parameters here
                    // hasVariableWidth = true
                    // listener = yourCustomListener
                }
                return presenter;
            }
        });
    }
    ...
Run Code Online (Sandbox Code Playgroud)

如果您需要片段中的单个实例LiveShowCardPresenter,则可以对其执行字段注入,而无需Provider. 或者,您可以在片段中注入所有依赖项并将它们传递给LiveShowCardPresenter构造函数。