Рукоять кинжала в Android с примером
Внедрение зависимостей (DI) — это шаблон проектирования для разделения обычных отношений зависимости между объектами. Когда дело доходит до DI в Android, Dagger всегда лидирует. Но это очень сложно и требует много стандартных кодов для настройки Dagger. Итак, чтобы преодолеть эту проблему, была введена рукоять . Dagger Hilt упрощает весь процесс и сокращает количество ненужных шагов, не теряя при этом никаких функций оригинального Dagger.
Пример
В этом примере мы создадим приложение для Android, которое будет отображать список криптовалют, используя шаблон проектирования MVVM, а для внедрения зависимостей мы будем использовать Dagger Hilt.
Шаг 1: Создайте новый проект
Чтобы создать новый проект в Android Studio, обратитесь к разделу «Как создать/запустить новый проект в Android Studio». Обратите внимание, что выберите Kotlin в качестве языка программирования.
Шаг 2: Добавление зависимостей
Чтобы использовать Dagger Hilt, нам нужно добавить для него зависимости. Во-первых, мы добавим classpath в наш файл build.gradle на уровне проекта . Чтобы добавить эту зависимость, перейдите в Gradle Scripts > build.gradle(Project:app) и добавьте следующую зависимость. После добавления этих зависимостей вам нужно нажать «Синхронизировать сейчас» .
dependencies {
classpath "com.google.dagger:hilt-android-gradle-plugin:2.38.1"
}Теперь в файле build.gradle уровня приложения нам нужно разместить плагин. Для этого перейдите в Gradle Scripts > build.gradle(Module:app) и добавьте следующий плагин.
plugins {
id "kotlin-android"
id "kotlin-kapt"
id "dagger.hilt.android.plugin"
}Нам также нужно добавить зависимость в тот же файл build.gradle уровня приложения. В build.gradle(Module:app) необходимо добавить следующую зависимость.
dependencies {
implementation "com.github.bumptech.glide:glide:4.9.0"
implementation "com.google.dagger:hilt-android:2.38.1"
kapt "com.google.dagger:hilt-android-compiler:2.38.1"
kapt "androidx.hilt:hilt-compiler:1.0.0"
implementation "androidx.activity:activity-ktx:1.4.0"
}Нам также нужно добавить атрибуты свойств в файл gradle.properties . Перейдите в Gradle Scripts > gradle.properties и добавьте следующее свойство.
kapt.use.worker.api=false
После добавления плагинов и зависимостей нужно нажать «Синхронизировать сейчас» . Прежде чем двигаться дальше, давайте добавим некоторые цветовые атрибуты, чтобы улучшить панель приложения. Перейдите в приложение > res > values > colors.xml и добавьте следующие атрибуты цвета.
XML
<resources> <color name="colorPrimary">#0F9D58</color> <color name="colorPrimaryDark">#16E37F</color> <color name="colorAccent">#03DAC5</color></resources> |
Шаг 3: Создание класса HiltApplication
На этом этапе мы создадим класс HiltApplication.kt и аннотируем этот класс аннотациями @HiltAndroidApp . Это заставит этот класс запускать генерацию кода Hilt, который будет иметь базовый класс для нашего приложения и действовать как контейнер зависимостей на уровне приложения. Для этого перейдите в app > java > package > щелкните правой кнопкой мыши > New > Kotlin Class/File и назовите его HiltApplication .
Kotlin
import android.app.Applicationimport dagger.hilt.android.HiltAndroidApp@HiltAndroidAppclass HiltApplication :Application(){} |
Как только мы закончим с этим, нам нужно обновить наш файл AndroidManifest.xml, указав имя нашего класса HiltApplication.kt как android:name внутри тега <application></application>. Кроме того, нам нужно добавить разрешение на доступ в Интернет в файле AndroidManifest.
XML
<uses-permission android:name="android.permission.INTERNET" /><application android:name=".HiltApplication" ></application> |
Шаг 4: Создание класса данных и репозитория
На этом шаге сначала мы создадим класс Data и назовем его Cryptocurrency. Этот класс будет иметь два изображения переменных-членов и имя. Для этого перейдите в app > java > package > щелкните правой кнопкой мыши > New > Kotlin Class/File .
Kotlin
data class Cryptocurrency( val image:String, val name:String) |
Теперь мы создадим класс Repository, в котором будет несколько примеров данных, которые мы введем в нашу ViewModel. Мы сделаем этот репозиторий абстрактным, сделав его интерфейсом и предоставив ему реализацию. Для создания этого перейдите в приложение > java > package > Щелкните правой кнопкой мыши > New > Kotlin Class/File и сделайте его тип интерфейсом, дайте ему имя CryptocurrencyRepository и добавьте к нему следующий код интерфейса.
Kotlin
interface CryptocurrencyRepository { fun getCryptoCurrency(): List<Cryptocurrency>} |
Теперь мы обеспечим реализацию этого класса интерфейса. Для этого перейдите в приложение > java > package > щелкните правой кнопкой мыши > New > Kotlin Class/File и создайте новый класс и назовите его CryptocurrencyRepositoryImpl.kt. В этом классе мы переопределим метод getCryptoCurrency() и предоставим ему реализацию. . Класс данных криптовалюты будет иметь два атрибута строкового типа: один для изображения, а другой для имени.
Kotlin
class CryptocurrencyRepositoryImpl : CryptocurrencyRepository{ // Overriding the interface method and // providing implementation to it override fun getCryptoCurrency() = listOf( // here we are adding images from wikipedia Cryptocurrency("https://upload.wikimedia.org/wikipedia/commons/thumb/9/9a/BTC_Logo.svg/1200px-BTC_Logo.svg.png", "BitCoin"), Cryptocurrency("https://upload.wikimedia.org/wikipedia/commons/thumb/0/01/Ethereum_logo_translucent.svg/1200px-Ethereum_logo_translucent.svg.png", "Ethereum"), Cryptocurrency("https://upload.wikimedia.org/wikipedia/commons/thumb/1/12/Binance_logo.svg/1920px-Binance_logo.svg.png", "Binance"), Cryptocurrency("https://upload.wikimedia.org/wikipedia/commons/thumb/e/e3/Litecoin_Logo.jpg/2048px-Litecoin_Logo.jpg", "LiteCoin"), Cryptocurrency("https://upload.wikimedia.org/wikipedia/commons/5/56/Stellar_Symbol.png", "Stellar"), Cryptocurrency("https://upload.wikimedia.org/wikipedia/commons/5/59/Polkadot_Logotype_color.png", "Polkadot"), )} |
Шаг 5: Создание класса модуля
На этом шаге мы создадим класс модуля и назовем его AppModule. Для этого перейдите в app > java > package > щелкните правой кнопкой мыши > New > Kotlin Class/File и создайте новый класс и назовите его AppModule.kt . Класс AppModule будет внедрять зависимость в другие классы, поэтому нам нужно аннотировать этот класс аннотацией @Module , которая сделает этот класс модулем для внедрения зависимости в другие классы в пределах его области. Кроме того, мы также добавим к нему еще одну аннотацию. то есть, @InstallIn(SingletonComponent::class) заставит этот класс внедрять зависимости во всё приложение.
Kotlin
import dagger.Moduleimport dagger.Providesimport dagger.hilt.InstallInimport dagger.hilt.components.SingletonComponentimport javax.inject.Singleton// @Module annotation which will make this class a module// to inject dependency to other class within it"s scope.// @InstallIn(SingletonComponent::class) this will make// this class to inject dependencies across the entire application.@Module@InstallIn(SingletonComponent::class)class AppModule { @Provides @Singleton fun provideCryptocurrencyRepository():CryptocurrencyRepository=CryptocurrencyRepositoryImpl()} |
Здесь мы также добавили положение для CryptocurrencyRepository, используя аннотацию @Provides . Наряду с этим мы использовали аннотацию @Singleton , чтобы всякий раз, когда мы внедряем зависимость, мы вводили один и тот же единственный экземпляр CryptocurrencyRepository, который когда-либо запрашивался.
Шаг 6: Создание ViewModel
На этом шаге мы создадим ViewModel. Для этого перейдите в приложение > java > пакет > Щелкните правой кнопкой мыши > Создать > Класс/файл Kotlin , создайте новый класс и назовите его MainViewModel.kt. Мы аннотируем его с помощью @HiltViewModel , что позволяет создавать модели с использованием фабрики моделей Hilt, что упрощает использование с действиями и фрагментами. Мы также аннотируем только один конструктор с помощью аннотации @Inject, используя этот конструктор, мы будем внедрять все зависимости в наш класс модели представления. Ниже приведен код класса MainViewModel.kt.
Kotlin
import androidx.lifecycle.LiveDataimport androidx.lifecycle.MutableLiveDataimport androidx.lifecycle.ViewModelimport dagger.hilt.android.lifecycle.HiltViewModelimport javax.inject.Inject// @HiltViewModel will make models to be// created using Hilt"s model factory// @Inject annotation used to inject all// dependencies to view model class@HiltViewModelclass MainViewModel @Inject constructor( private val cryptocurrencyRepository: CryptocurrencyRepository) : ViewModel() { private val cryptocurrencyEmitter = MutableLiveData<List<Cryptocurrency>>() val cryptoCurrency: LiveData<List<Cryptocurrency>> = cryptocurrencyEmitter init { loadCryptocurrency() } // getting cryptocurrencies list using // repository and passing it into live data private fun loadCryptocurrency() { cryptocurrencyEmitter.value = cryptocurrencyRepository.getCryptoCurrency() }} |
Шаг 7: Создайте класс адаптера
На этом шаге мы создадим адаптер. Для этого перейдите в приложение > java > пакет > Щелкните правой кнопкой мыши > Создать > Класс/файл Kotlin , создайте новый класс и назовите его CryptocurrencyAdapter.kt. Это обеспечит доступ к нашим элементам данных о криптовалюте и будет отвечать за создание представления для каждого элемента в списке данных о криптовалюте.
Kotlin
import android.view.LayoutInflaterimport android.view.Viewimport android.view.ViewGroupimport android.widget.TextViewimport androidx.recyclerview.widget.RecyclerViewimport com.bumptech.glide.Glideclass CryptocurrencyAdapter(private val cryptocurrency: List<Cryptocurrency>) : RecyclerView.Adapter<CryptocurrencyAdapter.ViewHolder>() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { // Inflating list data from list_item to view val view = LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false) return ViewHolder(view) } // Binding cryptocurrency list to ViewHolder override fun onBindViewHolder(holder: ViewHolder, position: Int) { holder.bind(cryptocurrency[position]) } override fun getItemCount() = cryptocurrency.size // Iterating ViewHolder and loading it"s // content to our Image and Text ViewsT class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { fun bind(index: Cryptocurrency) { // Here, we are using Glide library to // load the image into ImageView Glide.with(itemView.context) .load(index.image).dontAnimate() .into(itemView.findViewById(R.id.image)) // Setting name of cryptocurrency to TextView itemView.findViewById<TextView>(R.id.cryptocurrency).text = index.name } }} |
Шаг 8: Создайте файл list_item.xml
На этом шаге мы создадим файл list_item.xml, который будет содержать представления для нашего изображения и название криптовалюты. Для этого перейдите в приложение > res > layout > щелкните правой кнопкой мыши > New > Layout Resource File и создайте файл ресурсов, назовите его list_item.xml и добавьте в него следующие строки кода.
XML
<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="16dp" android:layout_margin="8dp" android:background="#f5f5f5" <ImageView android:id="@+id/image" android:layout_width="64dp" android:layout_height="64dp" android:scaleType="fitXY" android:layout_margin="24dp" android:importantForAccessibility="no" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" /> <!--text used are only for understanding purpose it will be removed at the runtime--> <TextView android:id="@+id/cryptocurrency" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="24dp" android:textSize="24sp" app:layout_constraintStart_toEndOf="@id/image" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" tools:text="Cryptocurrencies" /> </androidx.constraintlayout.widget.ConstraintLayout> |
Шаг 9: Создайте файл activity_main.xml
На этом этапе мы создадим макет для нашего файла activity_main.xml. Мы просто добавим RecyclerView в наш макет.
XML
<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/cryptocurrency_list" &n
РЕКОМЕНДУЕМЫЕ СТАТЬИ |