見出し画像

『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


いいなと思ったら応援しよう!