Внедрить абстрактный класс (базовое действие) с помощью HILT - PullRequest
1 голос
/ 02 августа 2020

Я только начинаю пробовать использовать Hilt в своем очень простом проекте. Пока все это было на Dagger2, но я хотел бы перейти на Hilt.

У меня есть активность:

@AndroidEntryPoint
class MainActivity : BaseActivity() { 
    // SOME STUFF
}

И BaseActivity вроде этого:

abstract class BaseActivity : AppCompatActivity() {
    // SOME STUFF
}

Кроме того, у меня есть класс, использующий baseActivity для отображения диалогового окна. Например:

@FragmentScoped
class TestComponentImpl @Inject constructor(
    private val baseActivity: BaseActivity
) : TestComponent {

    override fun displayDialog() {
        MaterialDialog(baseActivity).show { ... 
    }
}

Однако, когда я пытаюсь скомпилировать, у меня появляется следующая ошибка:

BaseActivity не может быть предоставлен без метода с аннотацией @ Provides.

Итак, мой вопрос: как конструктор внедрить абстрактный класс. Я много чего пробовал, но безуспешно, например, в модуле Hilt:

    @Provides
    @Singleton
    fun provideBaseActivity(): BaseActivity{
        return BaseActivity() // Of course, it can't work cause it's an abstract class
    } 

ИЛИ (как я сделал с Dagger):

    @Provides
    @PerActivity
    fun appCompatActivity(baseActivity: BaseActivity) = baseActivity as AppCompatActivity

Кроме того, я просто новичок с Hilt, может, я что-то упустил. Буду продолжать поиск :)

Спасибо за ваше время и ответы :)

РЕДАКТИРОВАТЬ:

Я искал самостоятельно несколько дней и это, похоже, работает, но не очень хорошо ...

@Singleton
@Provides
fun provideBaseActivity(baseActivity: BaseActivity): AppCompatActivity {
    return baseActivity
}

Но только если я поставлю свою baseActivity следующим образом:

open class BaseActivity Inject constructor() : AppCompatActivity() 

Однако после этого, если я попробуйте использовать мою внедренную baseActivity в моем TestComponentImpl следующим образом (как я делал с Dagger до Hilt):

override fun displayError() {
    Snackbar.make(
        baseActivity.findViewById(android.R.id.content),
        "My error text",
        Snackbar.LENGTH_LONG
    ).apply {
        show()
    }

У меня другая ошибка:

java .lang.NullPointerException: попытка вызвать виртуальный метод 'android .content.pm.ApplicationInfo android .content.Context.getApplicationInfo ()' для ссылки на нулевой объект

Так что я не Не думаю, что моя инъекция baseActivity полностью сделана. Продолжаю исследовать;)

1 Ответ

0 голосов
/ 05 августа 2020

Немного хакерский ( приведение типов ), но должно работать ( непроверено, списывая мне верхнюю часть головы, так что не стесняйтесь сообщать мне, если что-то работает не так, как ожидалось ):

Создайте такой Module:

@Module
@InstallIn(ActivityComponent::class)
object BaseActivityModule {

  @Provides
  fun provideBaseActivity(activity: Activity): BaseActivity {
    check(activity is BaseActivity) { "Every Activity is expected to extend BaseActivity" }
    return activity as BaseActivity  
  }
}

Последнее приведение as BaseActivity, вероятно, не нужно. Kotlin компилятор должен справиться с этим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...