■ きっかけ 
普通に、トップレベルの Composable内で State/Flow/StateFlow を返す ViewModel に接続します。
Composable ↔ ViewModel (↔ Repository)
 
👉 Hilt と Navigation 
一般的な NavHostController を使う場合には、それは NavBackStackEntryインスタンス となり 一つの Activity の上にスタック上に積まれていく。
👉 Composable の LifecycleOwner は誰なのか - collectAsStateWithLifecycle 
NavBackStackEntry3 - Composable3 ↔ ViewModel3 
NavBackStackEntry2 - Composable2 ↔ ViewModel2
NavBackStackEntry1 - Composable1 ↔ ViewModel1
Activity
 
ライフサイクル上、Activity と NavBackStackEntry との関係は良さそうです。
外側のActivityやFragmentがonStop状態になっていればこのNavBackStackEntryのlifecycleはCREATED状態になってくれていそうにみえます。
 
👉 ComposeNavigationで使えるNavBackStackEntryのlifecycleとは?  
👉 NavBackStackEntryのLifecycleについて | by Kenji Abe | Medium 
Flow を扱う ViewModel と、
スタックされる NavBackStackEntry (Screen-Level Composable) のライフサイクル。
気になります。
目視したいです。
遷移によっては同じ Composable がスタックに積まれていくのもキモいし。 
 
■ 方法 
ViewModel の生き死には、
class TodoViewModel @Inject constructor(
) : ViewModel() {
  init {
    // log
  }
  override fun onCleared() {
    // log
  }
}
 
で確認します。
👉 ViewModel はいつ生まれていつ死ぬか 【→ Jetpack Compose】 
Composable - NavBackStackEntry のライフサイクルは、
LifecycleEventObserver { _, event ->
  // log event
}
 
を使います。hash 付けてます。
👉 DisposableEffect: クリーンアップが必要な作用 
遷移先となる Composale に貼ります。
@Composable
fun TodoScreen(
  viewModel: TodoViewModel = hiltViewModel()
) {
  LocalLifecycleStateLogger(" TodoScreen") // *
 
@Composable
fun PokeScreen(
  viewModel: TodoViewModel = hiltViewModel()
) {
  LocalLifecycleStateLogger(" PokeScreen") // *
 
ついでに、これらの親となる NavHostController をセットしている Composale にも貼ります。
@Composable
fun MainScreen() {
  SystemUi(rememberSystemUiController())
  LocalLifecycleStateLogger(screenName = "MainScreen") // *
  val navHostController = rememberNavController()
 
 
■ 結果 
BottomNavigation をつかっていますが、スタックや saveState の設定はデフォルトのままなので、navigation を使っている場合は同様ではないかと思います。
アプリ起動
  ↓ ① click
TodoScreen
  ↓ ② click
PokeScreen
  ↓ ③ click
TodoScreen
  ↓ ④ back
PokeScreen
  ↓ ⑤ back
TodoScreen
  ↓ ⑥ back
アプリ終了
 
 
VIDEO  
 
ログ出力結果。
D: @@@ MainScreen - MainActivity@a542ab9 -> ON_CREATE
D: @@@ MainScreen - MainActivity@a542ab9 -> ON_START
D: @@@ MainScreen - MainActivity@a542ab9 -> ON_RESUME
D: @@@  TodoViewModel@abae21d initialized.
D: @@@  TodoScreen - NavBackStackEntry@8ad648d7 -> ON_CREATE
D: @@@  TodoScreen - NavBackStackEntry@8ad648d7 -> ON_START
D: @@@  TodoScreen - NavBackStackEntry@8ad648d7 -> ON_RESUME
D: @@@  TodoScreen - NavBackStackEntry@8ad648d7 -> ON_PAUSE
D: @@@  TodoScreen - NavBackStackEntry@8ad648d7 -> ON_STOP
D: @@@  PokeViewModel@ad0cefd initialized.
D: @@@  PokeScreen - NavBackStackEntry@4049e1c3 -> ON_CREATE
D: @@@  PokeScreen - NavBackStackEntry@4049e1c3 -> ON_START
D: @@@  PokeScreen - NavBackStackEntry@4049e1c3 -> ON_RESUME
D: @@@  PokeScreen - NavBackStackEntry@4049e1c3 -> ON_PAUSE
D: @@@  PokeScreen - NavBackStackEntry@4049e1c3 -> ON_STOP
D: @@@  TodoViewModel@577b5b1 initialized.
D: @@@  TodoScreen - NavBackStackEntry@f1d51055 -> ON_CREATE
D: @@@  TodoScreen - NavBackStackEntry@f1d51055 -> ON_START
D: @@@  TodoScreen - NavBackStackEntry@f1d51055 -> ON_RESUME
D: @@@  TodoScreen - NavBackStackEntry@f1d51055 -> ON_PAUSE
D: @@@  TodoScreen - NavBackStackEntry@f1d51055 -> ON_STOP
D: @@@  PokeScreen - NavBackStackEntry@4049e1c3 -> ON_CREATE
D: @@@  PokeScreen - NavBackStackEntry@4049e1c3 -> ON_START
D: @@@  TodoScreen - NavBackStackEntry@f1d51055 -> ON_DESTROY
D: @@@  TodoViewModel@577b5b1 onCleared.
D: @@@  PokeScreen - NavBackStackEntry@4049e1c3 -> ON_RESUME
D: @@@  PokeScreen - NavBackStackEntry@4049e1c3 -> ON_PAUSE
D: @@@  PokeScreen - NavBackStackEntry@4049e1c3 -> ON_STOP
D: @@@  TodoScreen - NavBackStackEntry@8ad648d7 -> ON_CREATE
D: @@@  TodoScreen - NavBackStackEntry@8ad648d7 -> ON_START
D: @@@  PokeScreen - NavBackStackEntry@4049e1c3 -> ON_DESTROY
D: @@@  PokeViewModel@ad0cefd onCleared.
D: @@@  TodoScreen - NavBackStackEntry@8ad648d7 -> ON_RESUME
D: @@@  TodoScreen - NavBackStackEntry@8ad648d7 -> ON_PAUSE
D: @@@ MainScreen - MainActivity@a542ab9 -> ON_PAUSE
D: @@@  TodoScreen - NavBackStackEntry@8ad648d7 -> ON_STOP
D: @@@ MainScreen - MainActivity@a542ab9 -> ON_STOP
 
ログから 各Screen = NavBackStackEntry のスタック状態を考えます。
  -
  ↓ ① click
 TodoScreen1 ↔ TodoViewModel1
MainScreen1 - MainActivity
  ↓ ② click
 PokeScreen1 ↔ PokeViewModel1
 TodoScreen1 ↔ TodoViewModel1
MainScreen1 - MainActivity
  ↓ ③ click
 TodoScreen2 ↔ TodoViewModel2
 PokeScreen1 ↔ PokeViewModel1
 TodoScreen1 ↔ TodoViewModel1
MainScreen@1 - MainActivity
  ↓ ④ back
 PokeScreen1 ↔ TodoViewModel2
 TodoScreen1 ↔ TodoViewModel1
MainScreen1 - MainActivity
  ↓ ⑤ back
 TodoScreen1 ↔ TodoViewModel1
MainScreen1 - MainActivity
  ↓ ⑥ back
  -
 
それぞれの NavBackStackEntry のライフサイクルと ViewModel の状態が確認できました。
ホストの Composable のライフサイクルオーナーは、Activity であることも分かりました。
画面が遷移していくと、NavBackStackEntry はスタックされていき、 back (戻る操作) すると、NavBackStackEntry は ON_DESTROY され、スタックから取り除くかれ、それに対応する ViewModel も onCleard() されていきます。
なんとなく思うのは、今現在としては、ViewModel は、やっぱりあったほうがいいように思います。
👉 【Jetpack Compose】 ViewModel を捨てて Repository を Composable に直結する 
そのうち、
hiltViewModel<ViewModel>()
 
のように、Reposiitory や DataProvider を注入する
androidx.hilt.navigation.compose メソッドやアノテーションが出れば嬉しいです。
 
👉 Jetpack Compose without ViewModel / Twitter  
👉 Jim Sproch (@JimSproch) - Jetpack Composeのコンポーネントはなぜ返り値がないのか - Blog - Mori Atsushi  
もうこれは「UIもマルチスレッドな時代になった」と言っていいんすかね。
👉 User interface frameworks typically are single-threaded. Why is this so and what are the performance implications of this single-threading? - Quora   
👉 Are Multiple UI Threads Possible? | Apple Developer Forums  
(つづく...)