Если вы создавали свои приложения с помощью MVVM Architecutre с Dagger. Тогда, возможно, вы все устали от шаблонного кода Dagger-Android.

Я говорю об этих фрагментах кода, которые вы часто видите:

Класс Applicaiton

override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
    return DaggerAppComponent.builder().application(this).build()
}

Аннотации

@MapKey
@Target(AnnotationTarget.FUNCTION)
annotation class ViewModelKey(val value : KClass<out ViewModel>)
@Scope
@kotlin.annotation.Retention(AnnotationRetention.RUNTIME)
annotation class ActivityScope

и ViewModelFactory , и Component с модулями AndroidSupportInjectionModule и ViewModelFactoryModule и т. д. Так много повторяющегося кода.

Меньше кода с рукоятью кинжала

Team of Dagger недавно представила новую рукоять кинжала, основная цель которой - сократить этот шаблонный код.

Всего 3 шага и папка di вашего проекта готова.

1-шаг. Добавить зависимости

Build.gradle на уровне проекта:

buildscript {
    ext.hilt_version = "2.28-alpha"
    ...
    dependencies {
        ...
        classpath "com.google.dagger:hilt-android-gradle-plugin:$hilt_version"
    }
}

Build.gradle на уровне приложения

...
apply plugin: 'kotlin-kapt'
apply plugin: 'dagger.hilt.android.plugin'

android {
    ...
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = "1.8"
    }
}

dependencies {

    ...
    // Activity Ktx for injecting View Models with viewModels()
    implementation "androidx.activity:activity-ktx:1.1.0"
    //Dagger - Hilt
    implementation "com.google.dagger:hilt-android:$hilt_version"
    kapt "com.google.dagger:hilt-android-compiler:$hilt_version"
    ...

}

2-шаговый. Аннотируйте свой класс приложения

Класс приложения

@HiltAndroidApp
class MyApp: Application()

3 этапа: создание приложения ApplicaitonModule

Модуль приложения

Здесь вам нужно предоставить экземпляры объектов, которые вы хотите добавить в свой проект позже. В этом примере я предоставляю экземпляр String.

@Module
@InstallIn(ApplicationComponent::class)
object ApplicationModule {
    @Singleton
    @Provides
    fun providesString(): String = "SomeString"
}

Здесь с помощью @InstallIn(ApplicationComponent::class мы говорим Кинжалу установить этот модуль в класс ApplicationComponent , который создается рукоятью кинжала.

Приложения Android имеют только один класс Application. Таким образом, есть еще один ApplicationComponentgenerated класс. Модуль, установленный в ApplicationComponent, привязан к жизненному циклу приложения и используется для предоставления экземпляров области действия приложения.

Если мы аннотируем модуль с помощью @InstallIn(ActivityComponent::class), то модуль привязывается к жизненному циклу Activity и используется для предоставления экземпляров области действия.

То же самое для сгенерированных классов FragmentComponent, ViewComponent и ServiceComponent.

Вот и все. Вот и все.

Давайте вводим

В Hilt инъекция очень похожа на dagger android - вы используете @Inject annotation. А чтобы внедрить свои объекты в активность, фрагмент, службы или другие классы Android, вам необходимо аннотировать этот класс с помощью @AndroidEntryPoint.

Давайте вставим строку, указанную в ApplicationModule, в нашу MainActivity.

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {

    @Inject
    lateinit var someStr: String

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        Log.d("TAG", someStr)
    }
}

Если вы запустите приложение, вы получите значение SomeString в someStrvariable.

Внедрение объектов ViewModel с помощью рукояти

Чтобы предоставить экземпляры ViewModel, вам необходимо аннотировать конструктор объекта ViewModel с помощью @ViewModelInject

class MainViewModel @ViewModelInject constructor() : ViewModel() { 
     ... 
}

Затем действие или фрагмент, помеченный @AndroidEntryPoint, может получить экземпляр ViewModel без @Inject, но, как обычно, с использованием ViewModelProvider или by viewModels() расширений KTX.

@AndroidEntryPoint
class MainActivity: AppCompatActivity() {
  private val mViewModel: MainViewModel by viewModels()
  ...
}

На этом пока все - надеюсь, вы узнали что-то полезное. Спасибо за чтение.

Если вы хотите сравнить использование двух разных кинжалов для реализации архитектуры MVVM, вы можете проверить эти 2 репозитория:

Https://github.com/SpiralDevelopment/MVVMPaging

Https://github.com/SpiralDevelopment/CryptoTracker

Переключайтесь между ветвями, чтобы увидеть различные реализации MVVM с использованием Dagger Android и Dagger Hilt.