![見出し画像](https://assets.st-note.com/production/uploads/images/170149596/rectangle_large_type_2_d2e47e81d8d9428870ac7e4c208a23cb.jpeg?width=1200)
『Android』 - ActivityとFragmentのライフサイクルの実行解析
概要
このブログは、ActivityとFragmentのライフサイクルの動きを解析し、その連動に関する詳細を解説します。コード例には3つのFragmentを利用しています。これらのFragmentを便宜事例として、より深く調査します。Fragmentの名前は「FragmentA」「FragmentB」「FragmentC」としています。
コード実装とライフサイクルログ
MainActivity
以下のコードで、Activityが開始すると、これらのFragmentを追加します。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Log.d("MainActivity", "onCreate: ");
supportFragmentManager.beginTransaction().add(R.id.container, fragmentA).commit()
supportFragmentManager.beginTransaction().add(R.id.container, fragmentB).commit()
supportFragmentManager.beginTransaction().add(R.id.container, fragmentC).commit()
}
実行結果
このコードの実行結果は次のようにログに出力されます:
D/MainActivity: onCreate:
D/FragmentA: onAttach:
D/FragmentA: onCreate:
D/FragmentA: onCreateView:
D/FragmentA: onViewCreated:
D/FragmentA: onActivityCreated:
D/FragmentB: onAttach:
D/FragmentB: onCreate:
D/FragmentB: onCreateView:
D/FragmentB: onViewCreated:
D/FragmentB: onActivityCreated:
D/FragmentC: onAttach:
D/FragmentC: onCreate:
D/FragmentC: onCreateView:
D/FragmentC: onViewCreated:
D/FragmentC: onActivityCreated:
D/FragmentA: onStart:
D/FragmentB: onStart:
D/FragmentC: onStart:
D/MainActivity: onStart:
D/MainActivity: onResume:
D/FragmentA: onResume:
D/FragmentB: onResume:
D/FragmentC: onResume:
ライフサイクルの連動と移動
MainActivityから移動した場合
MainActivityを移動すると、すべてのFragmentにライフサイクルの変化が起こります:
D/FragmentA: onPause:
D/FragmentB: onPause:
D/FragmentC: onPause:
D/MainActivity: onPause:
D/FragmentA: onStop:
D/FragmentB: onStop:
D/FragmentC: onStop:
D/MainActivity: onStop:
D/FragmentA: onDestroyView:
D/FragmentA: onDestroy:
D/FragmentA: onDetach:
D/FragmentB: onDestroyView:
D/FragmentB: onDestroy:
D/FragmentB: onDetach:
D/FragmentC: onDestroyView:
D/FragmentC: onDestroy:
D/FragmentC: onDetach:
D/MainActivity: onDestroy:
commitとcommitNowの違い
commit
commit は、後で実行するために操作を FragmentManager にキューに入れます。例えば:
supportFragmentManager.beginTransaction().add(R.id.container, fragmentA).commit()
Log.d("MainActivity", "fragment size: " + supportFragmentManager.fragments.size)
このコードは、commit完了後でもfragment sizeが0となります。
commitNow
commitNowを使用する場合:
supportFragmentManager.beginTransaction().add(R.id.container, fragmentC).commitNow()
Log.d("MainActivity", "fragment size: " + supportFragmentManager.fragments.size)
commitNowを使用すると、fragment sizeは実行直後に1となります。
Replace, Remove, Detachの違い
Replace
replaceは、指定されたコンテナ内のすべてのFragmentを置き換える操作です。以下のコード例では、FragmentAとFragmentBを追加した後、FragmentCで置き換えます:
supportFragmentManager.beginTransaction().add(R.id.container, fragmentA).commitNow()
supportFragmentManager.beginTransaction().add(R.id.container, fragmentB).commitNow()
Log.d("MainActivity", "fragment size: " + supportFragmentManager.fragments.size)
supportFragmentManager.beginTransaction().replace(R.id.container, fragmentC).commitNow()
Log.d("MainActivity", "fragment size: " + supportFragmentManager.fragments.size)
結果:
D/MainActivity: fragment size: 2
D/FragmentC: onAttach:
D/FragmentC: onCreate:
D/FragmentB: onDestroy:
D/FragmentB: onDetach:
D/FragmentA: onDestroy:
D/FragmentA: onDetach:
D/MainActivity: fragment size: 1
Remove
removeは、指定したFragmentをコンテナから削除します。以下のコード例では、FragmentAを削除します:
supportFragmentManager.beginTransaction().add(R.id.container, fragmentA).commitNow()
Log.d("MainActivity", "fragment size: " + supportFragmentManager.fragments.size)
supportFragmentManager.beginTransaction().remove(fragmentA).commitNow()
Log.d("MainActivity", "fragment size: " + supportFragmentManager.fragments.size)
結果:
D/MainActivity: fragment size: 1
D/FragmentA: onDestroy:
D/FragmentA: onDetach:
D/MainActivity: fragment size: 0
Detach
detachは、FragmentのViewを破棄しますが、Fragment自体は管理下に残ります。以下のコード例では、FragmentAをデタッチします:
supportFragmentManager.beginTransaction().add(R.id.container, fragmentA).commitNow()
Log.d("MainActivity", "fragment size: " + supportFragmentManager.fragments.size)
supportFragmentManager.beginTransaction().detach(fragmentA).commitNow()
Log.d("MainActivity", "fragment size: " + supportFragmentManager.fragments.size)
結果:
D/FragmentA:onAttach:
D/FragmentA:onCreate:
D/MainActivity: fragment size: 1
....
D/FragmentA: onDestroyView:
D/MainActivity: fragment size: 0