Android Dagger基本知識與簡單測試

簡要

看此篇前

如果還不清楚依賴項注入是什麼,可以參考這篇Android 依賴項注入(Dependency injection)

如果不知道Android怎麼測試資料,參考這篇如何使用Android Studio 測試資料?


Android 應用中手動依賴項注入或服務器可能會出現問題,具體實現項目的大小

Dagger 會自動生成代碼,因為該代碼是在編譯時生成的,因此具有可緩性,而且性能要取決於其他問題的解決方案

注意:使用 Hilt 可在 Android 上實現依賴注入。Hilt 在 Dagger 的基礎上構建,提供了一種將 Dagger 依賴項注入 Android 應用的標準方法。

在構建時,Dagger 會走查您的代碼,並執行以下操作:

  • 構建並驗證依賴關係圖,確保:

・每個對象的依賴關係都可以得到滿足,從而避免出現運行時異常。
・不存在任何依賴循環,從而避免出現無限循環。

  • 生成在運行時用於創建實際對象及其依賴項的類。

備註:@Component自動生成的容器前面會加上Dagger

如果找不到,Android Studio先Rebuild Project

因為Dagger是自動生成,發生編譯錯誤,做一次這個操作,基本上就正常了

1. Android使用Dagger前置作業

打開app build.gradle,頂端新增

plugins {
    id 'kotlin-kapt'
}

下方新增

dependencies {

    implementation 'com.google.dagger:dagger:2.33'
    kapt 'com.google.dagger:dagger-compiler:2.33'
}

新增完後記得Rebuild Project,否則可能會發生無法使用問題

2. 基本使用方法

這裡主要先把基礎打好,否則後面會越看越看不懂

讓Dagger知道如何創建實例

首先先新增UserLocalDataSource、UserRemoteDataSource這兩個class

class UserLocalDataSource @Inject constructor() {

}
class UserRemoteDataSource @Inject constructor() {

}

注意這邊多了@Inject這個,是告訴Dagger如何創建實例

再來新增一個UserRepository

class UserRepository @Inject constructor(
private val localDataSource: UserLocalDataSource,
private val remoteDataSource: UserRemoteDataSource
) {

}

一樣告訴Dagger如何創建UserRepository實例

因為UserLocalDataSource、UserRemoteDataSource已經放入了@Inject

所以Dagger也會知道如何創建他們的實例

創建容器,提供對象及各自依賴項

@Component
interface ApplicationGraph {
fun repository(): UserRepository
}

UserRepository在上面已經讓Dagger知道如何創建了

這裡在ApplicationGraph上面新增@Component

會創建一個容器,就像手動注入依賴項時的操作一樣

這樣建立好後,接著可以測試一下結果

@Test
fun test() {
val applicationGraph: ApplicationGraph = DaggerApplicationGraph.create()

val userRepository: UserRepository = applicationGraph.repository()
val userRepository2: UserRepository = applicationGraph.repository()

assert(userRepository != userRepository2)
}

結果兩個userRepository是不相同的

Dagger作用域(Scoping with Dagger)

可以使用作用域註釋將某個對象的生命週期限定為其組件的生命週期。這意味著,每次需要提供該類型時,都會使用依賴項的同一實例

可以使用內建的@Singleton作用域的標示

也可以自定義作用域

使用方式在Dagger實例上與容器上面加入作用域標示,如下

//使用內建@Singleton標示作用域
@Singleton
@Component
interface ApplicationGraph {
    fun repository(): UserRepository
}

@Singleton
class UserRepository @Inject constructor(
    private val localDataSource: UserLocalDataSource,
    private val remoteDataSource: UserRemoteDataSource
) {

}


//使用自定義作用域
//自定義作用域
@Scope
@MustBeDocumented
@Retention(value = AnnotationRetention.RUNTIME)
annotation class MyCustomScope

@MyCustomScope
@Component
interface ApplicationGraph {
    fun repository(): UserRepository
}

@MyCustomScope
class UserRepository @Inject constructor(
    private val localDataSource: UserLocalDataSource,
    private val remoteDataSource: UserRemoteDataSource
) {

}

作用域設定好後,再來測試一下

val applicationGraph: ApplicationGraph = DaggerApplicationGraph.create()

val userRepository: UserRepository = applicationGraph.repository()
val userRepository2: UserRepository = applicationGraph.repository()

assert(userRepository == userRepository2)

會發現兩個是相同實例囉!

備註:設定好作用域後,每次調用 applicationGraph.repository() 時,都會獲得 UserRepository 的同一實例

以上內容參考Android 官網


相關文章

Android 依賴項注入(Dependency injection)Android 應用中使用Dagger-1
簡要
1. 非依賴項注入 vs 依賴項注入
2. 自動依賴項注入
簡要
建構方法
Android 應用中使用Dagger-2
1. Dagger 子组件
2. 為子組件分配作用域
3. 構建 Dagger 圖的最佳做法
4. 使用 Dagger 模塊

訂閱Codeilin的旅程,若有最新消息會通知。

廣告

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s

WordPress.com.

向上 ↑

%d 位部落客按了讚: