Application は Android アプリ全体を表すオブジェクトです。
SettingsViewModel(application: Application) : AndroidViewModel(application) のようなコードで出てくる Application は、アプリのライフサイクル全体で1つだけ存在するグローバルなコンテキストとして利用されます。
まず整理すると、
class SettingsViewModel(
application: Application
) : AndroidViewModel(application)
の application は、
val app = getApplication<Application>()
で ViewModel 内から取得できる「アプリそのもの」です。
Applicationの主な役割
1. アプリ全体の初期化
アプリ起動時に一度だけ生成されます。
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
// ライブラリ初期化
// ログ設定
// DI初期化
}
}
イメージ:
Android OS
↓
Application (1個)
↓
Activity
↓
Fragment
↓
Compose UI
2. グローバルなContextを提供する
Androidでは多くのAPIが Context を必要とします。
例えば:
val prefs = application.getSharedPreferences(
"settings",
Context.MODE_PRIVATE
)
や
application.filesDir
など。
Application は Context を継承しているため、
Application is-a Context
という関係になっています。
3. Activityより長生きする
例えば画面回転すると、
Activity破棄
↓
Activity再生成
されます。
しかし
Application
は破棄されません。
そのため、
- 設定
- データベース
- Repository
- シングルトン
などの管理に向いています。
なぜAndroidViewModelはApplicationを受け取るの?
普通のViewModelは
class SettingsViewModel : ViewModel()
です。
ViewModelの設計思想としては、
UIとビジネスロジックを分離し、ActivityやContextに依存させない
ことが推奨されています。
しかし実際には、
- SharedPreferences
- Room Database
- ファイル操作
などで Context が必要な場合があります。
そのため Android は
AndroidViewModel
を用意していて、
class SettingsViewModel(
application: Application
) : AndroidViewModel(application)
とすると、
val app = getApplication<Application>()
で安全にアプリケーションコンテキストを使えます。
Composeでは最近どう考える?
現在は
AndroidViewModel
を使うケースは減っています。
推奨される構成は、
Application
↓
Repository
↓
ViewModel
↓
Compose
です。
例えば:
class SettingsRepository(
private val context: Context
)
class SettingsViewModel(
private val repository: SettingsRepository
) : ViewModel()
ViewModel自身は Application を知らず、
必要な処理を Repository に任せます。
これはテストしやすく、依存関係もきれいになります。
概念的に一言で言うと
Application は
「アプリ全体で1つだけ存在する、最上位のContext(アプリ本体)」
です。
AndroidViewModel(application) で渡しているのは、
ViewModelからアプリ全体の設定・ストレージ・リソースなどにアクセスできるようにするための入口
と考えると分かりやすいです。