Dagger Hilt en Android con ejemplo

La inyección de dependencia (DI) es un patrón de diseño para desacoplar la relación de dependencia convencional entre objetos. Cuando se trata de DI en Android, Dagger siempre toma la delantera. Pero es muy complejo y requiere muchos códigos repetitivos para configurar la Daga. Entonces, para superar este problema , se introdujo Hilt . Dagger Hilt simplifica todo el proceso y reduce los pasos innecesarios sin perder ninguna de las características del Dagger original.

Ejemplo

En este ejemplo, crearemos una aplicación para Android que mostrará la lista de criptomonedas usando el patrón de diseño MVVM y para la inyección de dependencia, usaremos Dagger Hilt.

Paso 1: Crear un nuevo proyecto

Para crear un nuevo proyecto en Android Studio, consulte Cómo crear/iniciar un nuevo proyecto en Android Studio . Tenga en cuenta que seleccione Kotlin como lenguaje de programación.

Paso 2: Agregar dependencias

Para usar Dagger Hilt, necesitamos agregar las dependencias para ello. Primero, agregaremos el classpath a nuestro archivo build.gradle a nivel de proyecto . Para agregar esta dependencia, vaya a Gradle Scripts > build.gradle(Project:app) y agregue la siguiente dependencia. Después de agregar estas dependencias, debe hacer clic en Sincronizar ahora .

dependencies {
        classpath 'com.google.dagger:hilt-android-gradle-plugin:2.38.1'
    }

Ahora, en el archivo build.gradle a nivel de la aplicación, debemos colocar un complemento. Para esto, vaya a Gradle Scripts > build.gradle(Module:app) agregue el siguiente complemento.

plugins {
    id 'kotlin-android'
    id 'kotlin-kapt'
    id 'dagger.hilt.android.plugin'
}

También necesitamos agregar la dependencia en el mismo archivo build.gradle de nivel de aplicación. La siguiente dependencia debe agregarse dentro de build.gradle (Módulo: aplicación).

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"
}

También necesitamos agregar atributos de propiedad en el archivo gradle.properties . Vaya a Gradle Scripts > gradle.properties y agregue la siguiente propiedad.

kapt.use.worker.api=false

Después de agregar complementos y dependencias, debe hacer clic en Sincronizar ahora . Antes de continuar, agreguemos algunos atributos de color para mejorar la barra de la aplicación. Vaya a aplicación > res > valores > colores.xml y agregue los siguientes atributos de color. 

XML

<resources>
    <color name="colorPrimary">#0F9D58</color>
    <color name="colorPrimaryDark">#16E37F</color>
    <color name="colorAccent">#03DAC5</color>
</resources>

Paso 3: crear una clase HiltApplication

En este paso, crearemos una clase HiltApplication.kt y anotaremos esta clase con anotaciones @HiltAndroidApp . Esto hará que esta clase desencadene la generación de código de Hilt, que tendrá la clase base para nuestra aplicación y actuará como el contenedor de dependencias a nivel de la aplicación. Para esto, vaya a app > java > package > haga clic con el botón derecho en > New > Kotlin Class/File y asígnele el nombre HiltApplication .

Kotlin

import android.app.Application
import dagger.hilt.android.HiltAndroidApp
 
@HiltAndroidApp
class HiltApplication :Application(){
}

Una vez que hayamos terminado con esto, debemos actualizar nuestro archivo AndroidManifest.xml proporcionando nuestro nombre de clase HiltApplication.kt como android:name dentro de la etiqueta <application></application>. Además, debemos agregar el permiso de Internet en el archivo AndroidManifest.

XML

<uses-permission android:name="android.permission.INTERNET" />
 
<application
        android:name=".HiltApplication" >
</application>

Paso 4: crear una clase de datos y un repositorio

En este paso, primero, crearemos una clase de Datos y la llamaremos Criptomoneda. Esta clase tendrá dos imágenes de variables miembro y un nombre. Para esto, vaya a app > java > package > Haga clic con el botón derecho en > New > Kotlin Class/File .

Kotlin

data class Cryptocurrency(
    val image:String,
    val name:String
)

Ahora, crearemos una clase de Repositorio que tendrá algunos datos de muestra que inyectaremos en nuestro ViewModel. Haremos que este Repositorio sea abstracto convirtiéndolo en una interfaz y brindándole una implementación. Para crear esto, vaya a aplicación > java > paquete > haga clic con el botón derecho en > Nuevo > Clase/Archivo Kotlin y haga su tipo como interfaz y asigne su nombre como CryptocurrencyRepository y agregue el siguiente código de interfaz.

Kotlin

interface CryptocurrencyRepository {
    fun getCryptoCurrency(): List<Cryptocurrency>
}

Ahora, proporcionaremos una implementación para esta clase de interfaz. Para esto, vaya a aplicación> java> paquete> clic derecho> Nuevo> Clase/archivo Kotlin y cree una nueva clase y asígnele el nombre CryptocurrencyRepositoryImpl.kt. En esta clase, anularemos el método getCryptoCurrency() y le proporcionaremos una implementación. . La clase de datos de criptomonedas tendrá dos atributos de tipo string, uno para la imagen y otro para el nombre.

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/en/d/d0/Dogecoin_Logo.png", "DogeCoin"),
        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"),
    )
}

Paso 5: crear una clase de módulo

En este paso, crearemos una clase de módulo y la nombraremos AppModule. Para esto, vaya a app > java > package > Right-click > New > Kotlin Class/File y cree una nueva clase y asígnele el nombre AppModule.kt . La clase AppModule inyectará dependencia a otras clases, por lo que debemos anotar esta clase con la anotación @Module que hará de esta clase un módulo para inyectar dependencia a otras clases dentro de su alcance. Además, también le agregaremos una anotación más. es decir, @InstallIn(SingletonComponent::class) esto hará que esta clase inyecte dependencias en toda la aplicación.

Kotlin

import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import 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()
}

Aquí, también hemos agregado la provisión para CryptocurrencyRepository usando la anotación @Provides . Junto con esto, hemos utilizado la anotación @Singleton para que cada vez que inyectemos la dependencia, inyectemos la misma instancia única de CryptocurrencyRepository que alguna vez se solicitó.

Paso 6: Creación de un modelo de vista

En este paso, crearemos un ViewModel . Para hacerlo, vaya a aplicación > java > paquete > haga clic con el botón derecho en > Nuevo > Clase/Archivo de Kotlin y cree una nueva clase y asígnele el nombre MainViewModel.kt. Lo anotaremos con @HiltViewModel, que hace que los modelos se creen utilizando la fábrica de modelos de Hilt, lo que facilita su uso con Actividades y Fragmentos . También anotaremos exactamente un constructor con la anotación @Inject, usando este constructor inyectaremos todas las dependencias a nuestra clase de modelo de vista. A continuación se muestra el código de la clase MainViewModel.kt.

Kotlin

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import dagger.hilt.android.lifecycle.HiltViewModel
import 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
@HiltViewModel
class 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()
    }
}

Paso 7: crear una clase de adaptador

En este paso, crearemos un adaptador. Para hacerlo, vaya a aplicación > java > paquete > clic derecho > Nuevo > Clase/Archivo Kotlin y cree una nueva clase y asígnele el nombre CryptocurrencyAdapter.kt. Esto proporcionará acceso a nuestros elementos de datos de criptomonedas y será responsable de hacer una Vista para cada elemento en la lista de datos de criptomonedas.

Kotlin

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
 
class 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
        }
    }
}

Paso 8: Cree el archivo list_item.xml

En este paso, crearemos un archivo list_item.xml que contendrá las vistas de nuestra imagen y el nombre de la criptomoneda. Para esto, vaya a aplicación > res > diseño > haga clic con el botón derecho en > Nuevo > Archivo de recursos de diseño y cree un archivo de recursos y asígnele el nombre list_item.xml y agréguele las siguientes líneas de códigos.

XML

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="16dp"
    android:layout_margin="8dp"
    android:background="#f5f5f5"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto">
   
    <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>

Paso 9: Cree el archivo activity_main.xml

En este paso, haremos el diseño de nuestro archivo activity_main.xml. Simplemente agregaremos un RecyclerView a nuestro diseño.

XML

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
   
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/cryptocurrency_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
   
</androidx.constraintlayout.widget.ConstraintLayout>

Paso 10: Trabajar con el archivo MainActivity

Finalmente, trabajamos con nuestra MainActivity. Primero, lo anotamos con la anotación @AndroidEntryPoint que hará que la clase del componente (actividad, fragmentos, vistas, servicios y receptor de transmisión) esté lista para la inyección. Además, obtendremos nuestro ViewModel en MainActivity mediante el uso del delegado viewModles(). Después de eso, solo estamos observando nuestro LiveData.

Kotlin

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
   
      private lateinit var cryptocurrencyList: RecyclerView
   
    // viewModels() delegate used to get
    // by view models will automatically construct the viewmodels using Hilt
    private val viewModel:MainViewModel by viewModels()
     
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
         
          cryptocurrencyList = findViewById<RecyclerView>(R.id.cryptocurrency_list)
        cryptocurrencyList.layoutManager = LinearLayoutManager(this)
         
        observeCryptoCurrency()
    }
     
    // Observing the live data
    private fun observeCryptoCurrency() {
        viewModel.cryptoCurrency.observe(this) {
            cryptocurrencyList.adapter = CryptocurrencyAdapter(it)
        }
    }
}

Producción:

Publicación traducida automáticamente

Artículo escrito por ankur035 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *