Skip to content

Android Context 與限定詞

本指南涵蓋了 Android 特有的限定詞模式,特別是關於 Context 處理的部分。

INFO

關於一般的限定詞概念(具名、型別安全、列舉、JSR-330),請參閱 限定詞

Android Context - 無需限定詞

與 Hilt 不同,Koin 會自動提供 Android Context,而不需要限定詞。

Koin 的 Context 解析

kotlin
val androidModule = module {
    // Context 自動可用
    single {
        SharedPreferences(
            androidContext()  // 自動提供 Application Context
        )
    }

    single {
        NotificationManager(
            androidContext().getSystemService(Context.NOTIFICATION_SERVICE)
        )
    }
}

不需要 @ApplicationContext 或 @ActivityContext

在 Hilt 中,你需要:

kotlin
// Hilt 需要明確的限定詞
class MyRepository @Inject constructor(
    @ApplicationContext private val context: Context
)

在 Koin 中則是自動的:

kotlin
class MyRepository(
    private val context: Context  // 直接使用 Context 即可
)

val appModule = module {
    single { MyRepository(androidContext()) }
}

INFO

Koin 優點: androidContext() 函式一律提供 Application Context。不需要限定詞來區分 Application 與 Activity Context。

當你需要 Activity Context 時

在需要 Activity Context 的情況下,請不要注入它——直接使用即可:

kotlin
class ScreenMetrics(private val activity: Activity) {
    fun getScreenSize(): Point {
        val display = activity.windowManager.defaultDisplay
        return Point().also { display.getSize(it) }
    }
}

// 不要定義在模組中——直接在 Activity 中建立
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val metrics = ScreenMetrics(this)  // 直接使用 Activity Context
    }
}

WARNING

最佳實務: 避免將 Activity Context 注入到長生命週期的物件中。這會導致記憶體洩漏。對於生命週期比 Activity 更長的相依性,請使用 Application Context (androidContext())。

具備限定詞的 Android 相依性

當你需要多個 Android 特有相依性的配置時:

kotlin
val databaseModule = module {
    single(named("user_db")) {
        Room.databaseBuilder(
            androidContext(),
            UserDatabase::class.java,
            "user-database"
        ).build()
    }

    single(named("cache_db")) {
        Room.databaseBuilder(
            androidContext(),
            CacheDatabase::class.java,
            "cache-database"
        ).build()
    }
}

後續步驟