国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Android之Dagger&Hilt依賴注入使用指南

這篇具有很好參考價值的文章主要介紹了Android之Dagger&Hilt依賴注入使用指南。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

簡介

Dagger2 是一個 Dependency Injection(DI) 依賴注入框架。它提供給 JavaAndroid 使用,主要用于模塊間解耦、提高代碼的健壯性和可維護性。

使用了 IOC (控制反轉(zhuǎn))的思想,在編譯階段使用 APT 利用 Java 注解生成 Java 代碼,然后結(jié)合部分手寫代碼來完整依賴注入工作。

運行前需要先編譯一次項目,目的是用 APT 生成中間代碼。Dagger2 不使用反射,在編譯階段生成代碼,所以不會程序性能有影響。

Dagger2 官網(wǎng)

Dagger2 Github


IOC

解釋:

IOC 全名為 Inversion of Control ,概念大體是借助于“第三方”實現(xiàn)具有依賴關(guān)系的對象之間的解耦。

IOC和DI的區(qū)別:

Martin Fowler探討既然 IOC 是控制反轉(zhuǎn),到底哪些方面的控制被反轉(zhuǎn)了?其實是獲得依賴對象的過程被反轉(zhuǎn)了,控制反轉(zhuǎn)后,獲得依賴對象的過程從自身管理變成了 IOC 容器主動注入,后來給控制反轉(zhuǎn)取了更適合的名字“依賴注入”。實際上給出了實現(xiàn) IOC 的方法:依賴注入

Android之Dagger&Hilt依賴注入使用指南,# 依賴注入,android,kotlin,android-studio


Dagger2的注解

@Inject

@Inject 這個注解本身并沒有作用,它需要依賴于注入框架才具有意義,可以用來標記構(gòu)造函數(shù)、屬性和方法。

1.1 標記構(gòu)造函數(shù)
  • 被標記的構(gòu)造函數(shù)可以有 0個或多個依賴作為參數(shù)
  • 同一個類中最多只可以標記一個構(gòu)造函數(shù)
class People @Inject constructor(val name:String = "Tom")

注意在 Kotlin 中這種寫法是不被允許的,因為這等價于 Java 中的多個構(gòu)造方法 People(String name), People(),正確的寫法應(yīng)該是這樣:

data class People constructor(val name: String) {
    @Inject
    constructor() : this("Tom")
}
1.2 標記屬性
  • 被標記的屬性不能是 final 的,Kotlin中不能是 val
  • 被注入進的屬性不能用 private 修飾(是 Dagger2 不支持,而非 @Inject 不支持)
@Inject
lateinit var people:People
1.3 標記方法
  • 被標記的方法可以有 0個或多個依賴作為參數(shù)。
  • 方法不能是抽象的。
class HomeActivity : AppCompatActivity() {
    private lateinit var people:People

    @Inject
    fun setPeople(people:People){
        this.people = people
    }
}

這種方法注入和屬性注入并沒有什么本質(zhì)上的不同,實現(xiàn)效果也基本一樣。還有一種做法是 @Inject 標記被注入類的某個方法,該方法會在類的構(gòu)造方法之后接著被調(diào)用:

data class People constructor(val name: String) {
    @Inject
    constructor() : this("Tom")

    init {
        println("init:$name")
    }

    @Inject
    fun hello(){
        println("hello:$name")
    }
}

class HomeActivity : AppCompatActivity() {
    @Inject
    lateinit var people:People

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

        //執(zhí)行相關(guān)注入操作
        ...
        println(people.toString())
    }
}

運行結(jié)果是這樣的:

01-02 11:57:30.995 16601-16601/? I/System.out:  init:Tom
01-02 11:57:30.995 16601-16601/? I/System.out:  hello:Tom
01-02 11:57:30.995 16601-16601/? I/System.out:  People(name=Tom)

@Component

可以理解為一個注射器,可以算是 Dagger2 中最核心的一個注解,用來標記一個接口或者抽象類。使用 @Component 標記的接口,會在編譯時自動生成一個 Dagger+類名的實現(xiàn)類實現(xiàn)依賴注入。在 Component 中一般可以定義兩種方法:

@Module

用來標記類,為 Component 提供依賴,相當于告訴 Component,如果需要依賴可以來找我,當然前提是在 Component 中配置了該Module。同時 Module 可以通過 includes 依賴其他的 Module。

@Provides

用來標記 Module中的方法,該方法的返回類型是你需要提供的依賴類型。
舉個自己項目中的例子,我需要在presenter中創(chuàng)建一個pl2303對象,pl2303對象的創(chuàng)建又需要context和pl2303Interface,所以我們需要提供三個依賴,因為context在其他地方也要用,我們單獨提出來:

@Singleton

默認情況下,@Inject 獲取到的依賴對象是非單例的,要想實現(xiàn)單例,需要用 @Singleton 對Module中的provide方法和Conponent接口進行標注。


Dagger&Hilt的使用

模擬場景:假設(shè) App 需要使用 Retrofit 進行網(wǎng)絡(luò)訪問

1.1 添加依賴

build.gradle(:app) 里添加以下依賴庫

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

dependencies {
		...
  
    // ViewModel
    implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1"

    //Dagger - Hilt
    implementation "com.google.dagger:hilt-android:2.38.1"
    implementation "androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03"
    implementation "androidx.hilt:hilt-navigation-compose:1.0.0"
    kapt "com.google.dagger:hilt-android-compiler:2.37"
    kapt "androidx.hilt:hilt-compiler:1.0.0"

    // Retrofit
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
    implementation 'com.squareup.okhttp3:okhttp:5.0.0-alpha.3'
}

build.gradle(Dagger&Hilt) 里添加以下代碼

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

1.2 添加一個應(yīng)用程序類

/**
 *  這是一個應(yīng)用程序類,用于傳遞上下文
 *  需要在注冊清單中聲明這個文件
 */
@HiltAndroidApp
class MyApp :Application()
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <application
        android:name=".MyApp"
        ...
				>
        ...
    </application>

</manifest>

1.3 給 MainActivity 添加入口注解

@AndroidEntryPoint// 入口點注釋
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            DaggerHiltTheme {
                val viewModel = hiltViewModel<MyViewModel>()
            }
        }
    }
}

1.4 創(chuàng)建網(wǎng)絡(luò)訪問接口

interface MyApi {
		
  	//模擬網(wǎng)絡(luò)請求
    @GET("test")
    suspend fun doNetworkCall()

}

1.5 創(chuàng)建存儲庫接口

interface MyRepository {
  
    suspend fun doNetworkCall()
  
}

1.6 創(chuàng)建存儲庫實現(xiàn)類

/**
 *  問題:
 *  1、如何把 MyApi 放入我們的存儲庫中,因為存儲庫中需要 MyApi 這個依賴
 *  2、如何讓 Dagger-Hilt 知道我們想在這里使用 MyApi
 *
 *  解決方案:
 *  1、直接在構(gòu)造器里添加我們的 MyApi
 *  2、通過創(chuàng)建依賴注入的容器(Module)來幫助,使用@Inject注解通過構(gòu)造器注入
 */

class MyRepositoryImpl @Inject constructor(
    private val api: MyApi,
    private val appContext: Application
) : MyRepository {

    init {
        val appName = appContext.getString(R.string.app_name)
        println("Hello from the MyRepositoryImpl. The app name's $appName")
    }

    override suspend fun doNetworkCall() {
				//模擬網(wǎng)絡(luò)請求
    }
}

1.7 創(chuàng)建全局單例模塊

@Module
@InstallIn(SingletonComponent::class)// 安裝到單例組件
object AppModule {

    /**
     *  每當我們提出請求時,例如在存儲庫中嘗試注入 MyApi 實例,
     *  然后 DaggerHilt 會在其 Module 中查找是否能找到對應(yīng)的實例,
     *  如果找到,它將獲取實例并傳遞給存儲庫。
     */
    @Provides//告知這里提供了一個依賴
    @Singleton//單例范圍注釋
    fun provideMyApi(): MyApi {
        return Retrofit.Builder()
            .baseUrl("https://test.com")
            .build()
            .create(MyApi::class.java)
    }


    @Provides
    @Singleton
    fun provideMyRepository(
        api: MyApi,
        app: Application,
        @Named("hello1") hello: String
    ): MyRepository {
        return MyRepositoryImpl(api, app)
    }


    /**
     * 常見問題:
     * 如果我們所需要的依賴項的類型一樣,
     * DaggerHilt 如何知道傳遞哪個參數(shù)給我們?
     *
     * 解決方案:
     * 使用 @Named("") 注解標記,在傳參時也對應(yīng)加上這個注解即可
     */
    @Provides
    @Singleton
    @Named("hello1")
    fun provideString1() = "Hello 1"

    @Provides
    @Singleton
    @Named("hello2")
    fun provideString2() = "Hello 2"
}

1.8 單獨創(chuàng)建接口和抽象類的模塊

最佳實踐:如果想注入接口或者抽象類,有更簡單的方法實現(xiàn),在 di 包新建一個模塊

@Module
@InstallIn(SingletonComponent::class)
abstract class RepositoryModule {

    // 因為這里時提供依賴項的不同方式,所以這里不稱為提供,叫<綁定>
    @Binds
    @Singleton
    abstract fun bindMyRepository(
        myRepository: MyRepositoryImpl
    ): MyRepository
}

1.9 常見問題

2.1 相同類型的依賴項無法識別

當我們需要注入依賴時,在生產(chǎn)實例的模塊中查找到多個類型相同的實例時,又或者我們的依賴項的類型一樣時 DaggerHilt 如何知道傳遞哪個參數(shù)給我們。解決方案:使用 @Named("") 注解,代碼如下:

//使用 @Named("") 注解標記,在傳參時也對應(yīng)加上這個注解即可
@Provides
@Singleton
fun provideMyRepository(
    api: MyApi,
    app: Application,
    @Named("hello1") hello: String
): MyRepository {
    return MyRepositoryImpl(api, app,hello)
}


@Provides
@Singleton
@Named("hello1")
fun provideString1() = "Hello 1"

@Provides
@Singleton
@Named("hello2")
fun provideString2() = "Hello 2"
2.2 如何注入依賴項到 Service

想把依賴項注入到后臺運行的 Service 中,如果給 Service 創(chuàng)建構(gòu)造器注入是不起作用的,因為不能給 Service 構(gòu)造器,所以用(字段注入)注意字段注入不能是 Private,解決方案:使用字段注入代碼如下:

@AndroidEntryPoint
class MyService :Service(){

    @Inject
    lateinit var repository: MyRepository

    override fun onCreate() {
        super.onCreate()
        // 在 onCreate 執(zhí)行完后,可以直接調(diào)用 repository 進行網(wǎng)絡(luò)訪問不需要自己進行初始化
        //repository.doNetworkCall()
    }

    override fun onBind(p0: Intent?): IBinder? {
        return null
    }
}

rvice 構(gòu)造器,所以用(字段注入)注意字段注入不能是 Private,解決方案:使用字段注入代碼如下:文章來源地址http://www.zghlxwxcb.cn/news/detail-725947.html

@AndroidEntryPoint
class MyService :Service(){

    @Inject
    lateinit var repository: MyRepository

    override fun onCreate() {
        super.onCreate()
        // 在 onCreate 執(zhí)行完后,可以直接調(diào)用 repository 進行網(wǎng)絡(luò)訪問不需要自己進行初始化
        //repository.doNetworkCall()
    }

    override fun onBind(p0: Intent?): IBinder? {
        return null
    }
}

到了這里,關(guān)于Android之Dagger&Hilt依賴注入使用指南的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【SQL注入】Sqlmap使用指南(手把手保姆版)持續(xù)更新

    【SQL注入】Sqlmap使用指南(手把手保姆版)持續(xù)更新

    官網(wǎng)下載地址:https://github.com/sqlmapproject/sqlmap sqlmap 是一款開源的滲透測試工具,可以自動化進行SQL注入的檢測、利用,并能接管數(shù)據(jù)庫服務(wù)器。它具有功能強大的檢測引擎,為滲透測試人員提供了許多專業(yè)的功能并且可以進行組合,其中包括數(shù)據(jù)庫指紋識別、數(shù)據(jù)讀取和訪問

    2024年04月10日
    瀏覽(32)
  • 【通義千問】大模型Qwen GitHub開源工程學(xué)習筆記(1)-- 使用指南、依賴庫和軟件

    【通義千問】大模型Qwen GitHub開源工程學(xué)習筆記(1)-- 使用指南、依賴庫和軟件

    9月25日,阿里云開源通義千問140億參數(shù)模型Qwen-14B及其對話模型Qwen-14B-Chat,免費可商用。 立馬就到了GitHub去fork。 GitHub: GitHub - QwenLM/Qwen: The official repo of Qwen (通義千問) chat pretrained large language model proposed by Alibaba Cloud. 官方的技術(shù)資料也下載了,看這里==https://qianwen-res.oss-cn-b

    2024年02月03日
    瀏覽(19)
  • 2. 使用IDEA創(chuàng)建Spring Boot Hello項目并管理依賴——Maven入門指南

    2. 使用IDEA創(chuàng)建Spring Boot Hello項目并管理依賴——Maven入門指南

    前言:本文將介紹如何使用IDEA創(chuàng)建一個Spring Boot Hello項目,并通過Maven來管理項目的依賴。我們從項目的創(chuàng)建到代碼的編寫,再到項目的構(gòu)建和運行,一步步演示了整個過程。 ?? 作者簡介:作為某云服務(wù)提供商的后端開發(fā)人員,我將在這里與大家簡要分享一些實用的開發(fā)小

    2024年02月10日
    瀏覽(25)
  • 【2023最新版】超詳細Sqlmap安裝保姆級教程,SQL注入使用指南,收藏這一篇就夠了

    【2023最新版】超詳細Sqlmap安裝保姆級教程,SQL注入使用指南,收藏這一篇就夠了

    一、sqlmap簡介 sqlmap是一個自動化的SQL注入工具,其主要功能是掃描,發(fā)現(xiàn)并利用給定的URL進行SQL注入。目前支持的數(shù)據(jù)庫有MySql、Oracle、Access、PostageSQL、SQL Server、IBM DB2、SQLite、Firebird、Sybase和SAP MaxDB等 Sqlmap采用了以下5種獨特的SQL注入技術(shù) 基于布爾類型的盲注,即可以根據(jù)

    2024年02月10日
    瀏覽(26)
  • android speechRecognizer原生語音識別使用指南

    背景:語音拍照功能的實現(xiàn) 不讓用三方算法庫 所以只能選擇android 原生speechRecognizer 其實就是解決語音轉(zhuǎn)文字? 文字轉(zhuǎn)好了邏輯就很好處理 speechRecognizer的用法 SpeechRecognizer 位于 android.speech package 中 源碼:/frameworks/base/core/java/android/speech/SpeechRecognizer.java 即 谷歌Android SpeechRe

    2024年02月08日
    瀏覽(15)
  • Android widget 小部件使用指南強化版

    Android widget 小部件使用指南強化版

    小部件是主屏幕定制的一個重要方面。您可以將它們視為應(yīng)用程序最重要的數(shù)據(jù)和功能的“概覽”視圖,這些數(shù)據(jù)和功能可以直接在用戶的主屏幕上訪問。用戶可以在主屏幕面板上移動小部件,如果支持的話,還可以調(diào)整它們的大小以根據(jù)自己的喜好定制小部件中的信息量。

    2024年01月19日
    瀏覽(28)
  • Android SeekBar使用避坑指南

    Android SeekBar使用避坑指南

    SeekBar是Android原生UI組件,可以用來調(diào)節(jié)進度,廣泛應(yīng)用于音樂、視頻進度展示調(diào)控、音量、亮度調(diào)節(jié)等功能里。 SeekBar的使用很簡單,這里就不再介紹了,本文著重介紹一下作者最近在使用SeekBar遇到的幾個坑,希望大家以后可以避免。 如圖,如何去實現(xiàn)這樣一個可拖動進度

    2024年02月07日
    瀏覽(89)
  • Android 圖片加載庫之Coil詳解與使用指南

    Android 圖片加載庫之Coil詳解與使用指南

    了解Coil Android圖片加載庫的優(yōu)勢、集成方法和使用方式。掌握Coil的特點,如性能優(yōu)化、輕量級、易用性強,以及高級功能如GIF動態(tài)加載、圖片變換等。

    2024年02月08日
    瀏覽(22)
  • grasscutter 使用指南——Android/Windows/IOS端均已支持

    grasscutter是某二次元手游的開源后端,目前功能并不完整,但正在contributers正在全速開發(fā)中,未來可期。可以部署在linux和windows下,通過代理與各種平臺的客戶端進行交互。本文提供grasscutter的linux端部署(windows端比較簡單)、windows/andriod/ios端的客戶端連接指導(dǎo),其中安卓提

    2023年04月09日
    瀏覽(73)
  • Android-Library-開源庫-JCenter-&-JitPack-安裝使用指南

    Android-Library-開源庫-JCenter-&-JitPack-安裝使用指南

    [注冊地址](https://bintray.com/signup/oss ) 1.盡量不要在官網(wǎng)注冊,因為官網(wǎng)注冊的是企業(yè)版,我們需要的是個人版 2.直接關(guān)聯(lián) Github賬號進行注冊 登錄(建議) PS:如果Github賬戶使用了qq郵箱,163郵箱等可能會無法注冊,可以嘗試給Github賬戶 增加一個郵箱例如 Gmail 步驟2:在Bintra

    2024年04月17日
    瀏覽(43)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包