---
title: "Fragmentのライフサイクル呼び出し順｜Javaで押さえる13コールバックと落とし穴"
url: "https://www.issoh.co.jp/tech/details/4368/"
published: 2024-12-02
updated: 2026-08-13
categories: ["Java"]
publisher: "株式会社一創"
---

# Fragmentのライフサイクル呼び出し順｜Javaで押さえる13コールバックと落とし穴

AndroidのFragmentは、onAttachからonDetachまで13個のコールバックを持ちます。12個は決まった順番で呼ばれ、onSaveInstanceStateだけがAPIレベルと状況によって位置を変えます。この順番を取り違えると、Viewがまだ無い段階でfindViewByIdを呼んでクラッシュしたり、破棄したはずのViewを参照し続けてメモリリークを起こしたりします。この記事では、androidx.fragment 1.9.0（2026年8月12日リリース）を前提に、生成時と破棄時の呼び出し順、onCreateViewとonViewCreatedの分担、onDestroyViewで何を消すべきかを、Javaのコードで具体的に示します。

## まとめ：13コールバックの呼び出し順と実装分担3点

生成時は`onAttach`→`onCreate`→`onCreateView`→`onViewCreated`→`onViewStateRestored`→`onStart`→`onResume`の順で呼ばれます。破棄時は`onPause`→`onStop`→`onDestroyView`→`onDestroy`→`onDetach`で、`onSaveInstanceState`だけはAPI 28を境に`onStop`との前後が入れ替わり、さらにバックスタック上ではView破棄後に呼ばれることもあります。

実装で押さえるべき分担は3点です。`onCreateView`はレイアウトのinflateだけを行い、findViewByIdやリスナー設定は`onViewCreated`に置きます。LiveDataの購読は`this`ではなく`getViewLifecycleOwner()`を渡します。`onDestroyView`ではViewバインディングをnullに戻し、Fragment側にView参照を残しません。

そして`setRetainInstance`や`onActivityCreated`など、かつて定番だったAPIは現行のandroidx.fragmentでは非推奨です。置き換え先は本文の対照表にまとめました。以降で、呼び出し順の全体像から順に見ていきます。

## ライフサイクル13コールバックの呼び出し順

Fragmentのコールバックは、生成方向（上向き）と破棄方向（下向き）で対称に並びます。公式のライフサイクルガイドは「onAttach() is always called before any Lifecycle state changes」「onDetach() is always called after any Lifecycle state changes」と明記しており、この2つが必ず両端に来ます。ここで数える13個は、実装で日常的にオーバーライドするものに限っています。非推奨の`onActivityCreated`と、アニメーションやメニュー関連の`onCreateAnimation`・`onInflate`などは除いています。

| 順  | コールバック              | 局面 | この時点で書く処理           |
| -- | ------------------- | -- | ------------------- |
| 1  | onAttach            | 生成 | Contextの取得          |
| 2  | onCreate            | 生成 | Viewに依存しない初期化       |
| 3  | onCreateView        | 生成 | レイアウトのinflateのみ     |
| 4  | onViewCreated       | 生成 | View初期化・LiveData購読  |
| 5  | onViewStateRestored | 生成 | View状態の復元後の処理       |
| 6  | onStart             | 表示 | 子FragmentManagerの操作 |
| 7  | onResume            | 表示 | 操作受付・再生の再開          |
| 8  | onPause             | 離脱 | 操作受付・再生の停止          |
| 9  | onStop              | 離脱 | 更新処理の停止             |
| 10 | onSaveInstanceState | 離脱 | Bundleへの状態保存        |
| 11 | onDestroyView       | 破棄 | View参照の解放           |
| 12 | onDestroy           | 破棄 | Fragment全体の後始末      |
| 13 | onDetach            | 破棄 | Contextの切り離し        |

縦に並べると、Viewを扱える区間が3番から11番までに限られていることが見て取れます。

```
[生成]  onAttach
          ↓  onCreate
          ↓  onCreateView          ← inflate だけ
          ↓  onViewCreated         ← findViewById・購読開始
          ↓  onViewStateRestored   ← View状態はここで戻る
          ↓  onStart
          ↓  onResume
[表示中]
          ↓  onPause
          ↓  onStop
          ↓  onSaveInstanceState   ← API 28 以降の位置。27 以前は onStop の前
          ↓  onDestroyView         ← View 参照を null に戻す
          ↓  onDestroy
[破棄]  onDetach
```

### 生成時の呼び出し順とonViewStateRestoredの位置

検索でよく問われる「onCreateView、onAttach、onViewCreated、onStart、onCreateはどの順番か」の答えは、`onAttach`→`onCreate`→`onCreateView`→`onViewCreated`→`onStart`です。`onCreate`と`onCreateView`は隣り合っていますが、役割は別です。前者はViewが存在しない段階の初期化、後者はViewの生成そのものを担います。名前の近さと役割の遠さが取り違えの起点になります。

この2つの間に、忘れられがちな`onViewStateRestored`が挟まります。公式ガイドは、Viewが生成された後に以前のView状態が復元されてからViewのLifecycleがCREATEDへ移り、この遷移が`onViewStateRestored`を呼ぶと説明しています。つまりEditTextの入力内容やRecyclerViewのスクロール位置が戻るのは`onViewCreated`の後です。`onViewCreated`で入力欄を初期化すると、その後の復元で上書きされます。

`onCreate`が受け取るsavedInstanceStateには公式の注記があります。フラグメントが初めて生成されたときはnullですが、再生成のときは`onSaveInstanceState`をオーバーライドしていなくても常に非nullです。nullチェックだけで「初回かどうか」を判定できるのはこのためです。

### 破棄時の呼び出し順とonSaveInstanceStateが動く2つの条件

破棄方向は`onPause`→`onStop`→`onDestroyView`→`onDestroy`→`onDetach`です。androidxのFragment.javaのjavadocも、`onDestroyView`について「called after onStop() and before onDestroy()」と明記しています。

位置が動くのは`onSaveInstanceState`だけで、条件は2つあります。1つ目はAPIレベルです。公式ガイドは「For all API levels prior to API 28, onSaveInstanceState() is invoked before onStop(). For API levels 28 and higher, the calling order is reversed.」と述べています。API 27以前は`onPause`→`onSaveInstanceState`→`onStop`、API 28以降は`onPause`→`onStop`→`onSaveInstanceState`です。

2つ目はバックスタックです。Fragment.javaのjavadocは「this method may be called at any time before onDestroy(). There are many situations where a fragment may be mostly torn down (such as when placed on the back stack with no UI showing), but its state will not be saved until its owning activity actually needs to save its state.」と注意しています。バックスタックに積まれてUIを持たない、つまり`onDestroyView`を済ませたFragmentに対しても、後から`onSaveInstanceState`が呼ばれます。Viewがある前提で書いた保存処理はここで落ちるため、対処は後述のnullガードの項で示します。

なお`onSaveInstanceState`は破棄のたびに呼ばれるわけではありません。バックスタックに積まずに`remove()`したときやホストのActivityがfinishするときは状態が保存されないため、ここに書いた保存処理は使われずに消えます。

### 呼び出し順を実機で確認するJavaコード

順番は暗記するより、実装中のプロジェクトで1回ログに出したほうが確実です。まず依存関係を追加します。テスト用のartifactは2つに分かれており、公式のテストガイドは`fragment-testing-manifest`を`debugImplementation`で、`fragment-testing`を`androidTestImplementation`で宣言するよう示しています。

```
dependencies {
    def fragment_version = "1.9.0"

    implementation "androidx.fragment:fragment:$fragment_version"
    debugImplementation "androidx.fragment:fragment-testing-manifest:$fragment_version"
    androidTestImplementation "androidx.fragment:fragment-testing:$fragment_version"
}
```

次に、13コールバックすべてにログを仕込んだFragmentを用意します。画面を回転させる、ホームに戻る、バックキーで戻るといった操作をしながらlogcatをFragmentLifecycleタグで絞ると、状況ごとにどこまで下がってどこから戻るかが読み取れます。

```
public class LifecycleLogFragment extends Fragment {

    // ログの番号は API 28 以降の順序。API 27 以前は 10 が 9 より先に出る
    private static final String TAG = "FragmentLifecycle";

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        Log.d(TAG, "1 onAttach");
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "2 onCreate saved=" + (savedInstanceState != null));
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater,
                             @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState) {
        Log.d(TAG, "3 onCreateView");
        return inflater.inflate(R.layout.fragment_sample, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        Log.d(TAG, "4 onViewCreated");
    }

    @Override
    public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
        super.onViewStateRestored(savedInstanceState);
        Log.d(TAG, "5 onViewStateRestored");
    }

    @Override
    public void onStart() {
        super.onStart();
        Log.d(TAG, "6 onStart");
    }

    @Override
    public void onResume() {
        super.onResume();
        Log.d(TAG, "7 onResume");
    }

    @Override
    public void onPause() {
        super.onPause();
        Log.d(TAG, "8 onPause");
    }

    @Override
    public void onStop() {
        super.onStop();
        Log.d(TAG, "9 onStop");
    }

    @Override
    public void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        Log.d(TAG, "10 onSaveInstanceState");
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        Log.d(TAG, "11 onDestroyView");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "12 onDestroy");
    }

    @Override
    public void onDetach() {
        super.onDetach();
        Log.d(TAG, "13 onDetach");
    }
}
```

### FragmentScenarioによる呼び出し順の固定

ログでの確認は再現条件を人手で作るため、回帰の検知には向きません。fragment-testingが提供する`FragmentScenario`を使うと、任意のライフサイクル状態への遷移と構成変更の再生成をテストコードから直接起こせます。公式ガイドが「run each of the API’s methods in your test’s instrumentation thread」と指定しているとおり、置き場所は`app/src/androidTest`配下の計装テストです。

```
@RunWith(AndroidJUnit4.class)
public class ProfileFragmentTest {

    @Test
    public void restoresDraft_afterRecreate() {
        // FragmentScenario は Closeable なので try-with-resources で閉じる
        try (FragmentScenario<ProfileFragment> scenario =
                     FragmentScenario.launchInContainer(ProfileFragment.class)) {

            scenario.onFragment(fragment -> {
                EditText input = fragment.requireView().findViewById(R.id.draft_input);
                input.setText("下書き");
            });

            // CREATED まで落とすと onPause から onDestroyView まで実際に走る
            scenario.moveToState(Lifecycle.State.CREATED);
            scenario.moveToState(Lifecycle.State.RESUMED);
            scenario.recreate();

            scenario.onFragment(fragment -> {
                EditText input = fragment.requireView().findViewById(R.id.draft_input);
                assertEquals("下書き", input.getText().toString());
            });
        }
    }
}
```

`moveToState(Lifecycle.State.CREATED)`はViewの破棄までを、`recreate()`は画面回転と同じ再生成を再現します。構成変更とプロセス終了を人手で再現するのは手間がかかるため、復元を伴う画面にはこのテストを1本置く価値があります。

## フラグメントとは｜Activityとの役割分担

Fragmentは、Activityの中に埋め込んで使うUIの部品です。単体では画面として起動できず、FragmentManagerによって状態が管理されます。Activityとは別に自分自身のライフサイクルを持つため、持ち主より短命にも長命にもなります。この性質が、呼び出し順を難しくしている根本の理由です。

Activityはシステムから見た画面の単位で、マニフェストに登録され、インテントで起動されます。Fragmentはその内側に置く部品なので、1つのActivityに複数を同時に配置できます。タブレットで一覧と詳細を左右に並べ、スマートフォンでは1枚ずつ表示するといった出し分けは、この構造があって成立します。

公式ガイドには、Fragmentの状態はFragmentManagerの状態を超えられず、親より進んだ状態にもなれないという制約が示されています。親のActivityが開始される前に子のFragmentが開始されることはなく、逆に子は親より先に停止します。加えて、レイアウトXMLでFragmentを配置する`<fragment>`タグには「FragmentManagerの状態を超えて進んでしまう」という注意が付いており、`FragmentContainerView`を使うよう案内されています。なお実装対象のクラスは`androidx.fragment.app.Fragment`で、OS標準の`android.app.Fragment`は非推奨です。詳細は後半の対照表で扱います。

実装言語をこれから決める場合は、[Androidアプリ開発の言語はKotlinとJavaのどちらか？選定基準と環境まで解説](/tech/details/15321/)で選定基準を整理しています。

## onCreateViewとonViewCreatedの使い分け

旧来のサンプルには、`onCreateView`の中でinflateしたViewに対してfindViewByIdを呼び、そのままリスナーを設定するコードが多く残っています。androidxのFragment.javaのjavadocは、この書き方を明確に否定しています。「It is recommended to only inflate the layout in this method and move logic that operates on the returned View to onViewCreated()」、つまりこのメソッドではレイアウトのinflateだけを行い、返したViewを操作するロジックは`onViewCreated`へ移せ、という指示です。

対する`onViewCreated`について、公式ガイドは「Viewの初期状態の設定、Viewを更新するLiveDataの購読開始、RecyclerViewやViewPager2のアダプタ設定に適した場所」と説明しています。役割の線引きははっきりしていて、Viewを作るのが`onCreateView`、作られたViewを触るのが`onViewCreated`です。

```
private OrderViewModel viewModel;  // onCreate で ViewModelProvider から取得しておく

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
                         @Nullable ViewGroup container,
                         @Nullable Bundle savedInstanceState) {
    // inflate だけを行う。findViewById やリスナー設定は書かない
    return inflater.inflate(R.layout.fragment_order, container, false);
}

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    RecyclerView list = view.findViewById(R.id.order_list);
    OrderAdapter adapter = new OrderAdapter();  // ListAdapter を継承した実装
    list.setAdapter(adapter);

    // 購読の LifecycleOwner は this ではなく getViewLifecycleOwner()
    viewModel.getOrders().observe(getViewLifecycleOwner(), adapter::submitList);
}
```

この分離には実務上の効き目があります。`onCreateView`にView操作を書くと、Viewが再生成されるたびに走る処理と一度きりでよい処理が同じメソッドに同居し、バックスタックから戻ったときの二重初期化を追いにくくなります。

## Viewライフサイクルの独立とonDestroyViewでの参照解放

FragmentのViewは、Fragment本体とは別のLifecycleを持ちます。Fragment.javaのjavadocは「in cases of detached Fragments, the lifecycle of the Fragment can be considerably longer than the lifecycle of the View itself」と述べています。Fragmentは生きているのにViewだけが死んでいる期間が存在する、という点がonDestroyView関連のバグの原因です。

### Viewライフサイクルのイベント発火順

`getViewLifecycleOwner()`のjavadocは、ViewのLifecycleイベントが発火する位置をコールバック基準で列挙しています。ON\_CREATEは`onViewStateRestored`の後、ON\_STARTは`onStart`の後、ON\_RESUMEは`onResume`の後です。下向きは反転し、ON\_PAUSEは`onPause`の前、ON\_STOPは`onStop`の前、ON\_DESTROYは`onDestroyView`の前に発火します。

ViewのLifecycleが有効なのは`onDestroyView`の呼び出しまでです。javadocは、その後は`getView()`がnullを返し、ViewのLifecycleは破棄され、`getViewLifecycleOwner()`はIllegalStateExceptionを投げると明記しています。非同期処理の完了コールバックの中でこのメソッドを呼ぶ設計は、遅れて戻ってきた瞬間に落ちます。

### ViewBindingのnull化とLiveData購読の指定先

Viewが先に死ぬという性質から、実装の鉄則が2つ導かれます。1つはバインディングの解放です。公式ガイドは`onDestroyView`の時点で「all references to the fragment’s view should be removed」と述べています。Fragmentのフィールドにバインディングを持たせたままにすると、破棄済みのView階層がFragmentの寿命の間ずっと残ります。

```
private FragmentOrderBinding binding;

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
                         @Nullable ViewGroup container,
                         @Nullable Bundle savedInstanceState) {
    binding = FragmentOrderBinding.inflate(inflater, container, false);
    return binding.getRoot();
}

@Override
public void onDestroyView() {
    super.onDestroyView();
    // View より長生きする Fragment に参照を残さない
    binding = null;
}
```

もう1つがLiveDataの購読先です。`observe()`の第1引数に`this`を渡すとFragment本体の寿命に紐づくため、Viewが作り直されるたびに購読が積み重なります。すると1回の更新で、積み重なった回数だけコールバックが走ります。`getViewLifecycleOwner()`を渡せば、ON\_DESTROYの時点で購読が自動的に解除されます。バックスタックを使う画面でリストが二重に描画される症状は、この取り違えで再現します。

## 状態保存の使い分け｜onSaveInstanceState・ViewModel・バックスタック

「入力内容が消える」という不具合は、どの状態がどの操作で消えるかを把握していないことが原因です。公式の状態保存ガイドは、操作と状態の種類の組み合わせを表で示しています。VariablesはFragmentが持つ変数（原文は local variables in the fragment）、View Stateは各Viewが持つ値、SavedStateは`onSaveInstanceState`で保存する値、NonConfigはサーバーなど外部から取得したデータを指します。

### 操作別に生き残る状態の対応表

| 操作               | 変数  | View状態 | SavedState | NonConfig |
| ---------------- | --- | ------ | ---------- | --------- |
| バックスタックへの追加      | 残る  | 残る     | 消える        | 残る        |
| 構成変更             | 消える | 残る     | 残る         | 残る        |
| プロセス終了と再生成       | 消える | 残る     | 残る         | 条件付き      |
| バックスタックなしのremove | 消える | 消える    | 消える        | 消える       |
| ホストのfinish       | 消える | 消える    | 消える        | 消える       |

プロセス終了時のNonConfigは、ViewModel向けのSaved Stateモジュールを使う場合に限って残ります。表から読み取るべきは、バックスタックへの追加では変数が生き残る一方、構成変更では消えるという非対称です。バックスタックではFragmentのインスタンス自体が保持されるため`onCreate`は再実行されませんが、画面回転ではインスタンスが作り直されるため、フィールドに置いた値は`onSaveInstanceState`を通さない限り失われます。

### onSaveInstanceStateでViewを読むときのnullガード

ここで先ほどの`binding = null`と`onSaveInstanceState`が衝突します。バックスタック上のFragmentに対して`onSaveInstanceState`が呼ばれる時点で、bindingは既にnullです。保存処理をView経由で書くと、その瞬間にNullPointerExceptionで落ちます。Viewがある間に値をフィールドへ退避し、保存時はフィールドを使うのが安全な形です。

```
private static final String KEY_DRAFT = "draft_text";
private String draft = "";

@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
    // View がある間は View から、無い場合は退避済みの値から保存する
    if (binding != null) {
        draft = binding.draftInput.getText().toString();
    }
    outState.putString(KEY_DRAFT, draft);
}

@Override
public void onDestroyView() {
    super.onDestroyView();
    draft = binding.draftInput.getText().toString();  // View がある最後の機会に退避
    binding = null;
}

@Override
public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
    super.onViewStateRestored(savedInstanceState);
    if (savedInstanceState != null) {
        draft = savedInstanceState.getString(KEY_DRAFT, "");
        binding.draftInput.setText(draft);
    }
}
```

退避先のフィールドを増やしたくない場合は、値の置き場をViewModelの`SavedStateHandle`へ寄せる方法もあります。その場合はFragmentのコールバックから状態保存の責務自体が消えるため、上のガードも不要になります。

### setRetainInstanceの非推奨とViewModelへの置き換え

構成変更をまたいでデータを保持する目的で`setRetainInstance(true)`を使う解説は、いまも数多く出回っています。androidxのFragment.javaでこのメソッドは非推奨で、javadocの指示は「Fragment自体を保持するのではなく、非保持のFragmentを使い、保持したい状態はそのFragmentに紐づくViewModelに置け」というものです。ViewModelのコンストラクタと`onCleared()`が、保持する状態の生成と最終破棄の合図になるとも書かれています。

```
public class OrderViewModel extends ViewModel {

    private final MutableLiveData<List<Order>> orders = new MutableLiveData<>();

    public LiveData<List<Order>> getOrders() {
        return orders;
    }

    @Override
    protected void onCleared() {
        // 画面が完全に終了したときだけ呼ばれる。購読やジョブの停止はここ
    }
}

// Fragment 側（onCreate で取得してよい）
viewModel = new ViewModelProvider(this).get(OrderViewModel.class);
```

ViewModelへ寄せる利点は、破棄のタイミングが1か所に集約されることです。`setRetainInstance`ではFragment自身が生き残るため、Viewの破棄とデータの破棄が同じクラスに混在し、どちらの寿命の話をしているのかコードから読み取れなくなります。バックグラウンドで走らせたい処理そのものは、[WorkManagerとは？Androidの遅延実行の仕組みと採用判断を解説](/tech/details/16038/)で扱う仕組みに預けるほうが確実です。

## 呼び出し順に起因する典型障害と対処

ここまでの仕様から機械的に導ける不具合を2つ挙げます。どちらも呼び出し順の理解だけで回避できます。

### バックスタック復帰でonCreateが呼ばれない理由

公式ガイドは、バックスタックの最上位に積まれたFragmentがCREATEDからSTARTED、RESUMEDへと上がり、逆にバックスタックから取り出されるときはRESUMEDからSTARTED、CREATEDへ下がると説明しています。下限がCREATEDである以上、戻ってきたときの出発点もCREATEDで、`onCreate`は再実行されません。実際に走るのは`onCreateView`以降です。

`onCreate`にAPI呼び出しを書いた画面が、戻ったときだけデータを取り直さないのはこのためです。Viewが作り直されるたびに実行してよい処理は`onViewCreated`に置いてください。

### IllegalStateExceptionが出る2つの条件

ViewのLifecycleに関するIllegalStateExceptionには、発生条件が2つあります。1つは`onDestroyView`より後に`getViewLifecycleOwner()`を呼んだ場合です。もう1つは、`onCreateView`の中でViewのLifecycleへアクセスしながら非nullのViewを返さなかった場合で、javadocが明示的に警告しています。非同期の完了コールバックからViewを触る設計をやめ、ViewModelのLiveDataを経由してUIを更新すれば、どちらも構造的に起こりません。コルーチンでスコープを揃える方法は[Kotlin Coroutinesとは？suspendの仕組みと構造化並行性・採用判断](/tech/details/16036/)で整理しています。

## 非推奨APIと移行先の対照表

Fragmentの周辺APIは置き換えが続いており、古い解説をそのまま写すと非推奨のAPIに当たります。代替はいずれもFragment.javaの`@deprecated`javadocに書かれた指示に対応します。

| 非推奨API                  | 代替                             |
| ----------------------- | ------------------------------ |
| android.app.Fragment    | androidx.fragment.app.Fragment |
| onActivityCreated()     | onViewCreated() と onCreate()   |
| setRetainInstance(true) | ViewModel                      |
| setTargetFragment()     | setFragmentResultListener()    |
| setUserVisibleHint()    | setMaxLifecycle()              |
| setHasOptionsMenu()     | MenuProvider                   |
| <fragment>タグでの配置        | FragmentContainerView          |

1行目はライブラリの選択そのものです。APIリファレンスは`android.app.Fragment`を「Added in API level 11 / Deprecated in API level 28」と表示しており、現在の実装対象はJetpackの`androidx.fragment.app.Fragment`だけです。古いサンプルを写すときは、importが`android.app`で始まっていないかを最初に確認してください。

`onActivityCreated`はViewを触るコードを`onViewCreated`へ、それ以外の初期化を`onCreate`へ分けるよう案内されています。`setTargetFragment`は、要求側が`setFragmentResultListener()`でリクエストキーを登録し、結果を返す側が同じキーで`setFragmentResult()`を呼ぶ形に変わりました。javadocが指すのはFragmentManagerのメソッドなので、Javaでは`getParentFragmentManager()`から呼びます。

androidx.fragmentの最新安定版は1.9.0で、Google Mavenのメタデータ上の更新は2026年8月12日です。バージョンは短い周期で上がるため、採用時はGoogle Mavenの値を確認してください。同じ1.9.0では`fragment-compose`も配信されており、既存のFragmentを器として残したままUIをComposeへ移す経路が用意されています。

この対照表の長さ自体が判断材料になります。2026年の新規画面をFragmentの積み上げで設計する理由は薄いというのが筆者の見解です。まず新規画面をComposeで作り、既存画面は不具合対応のついでに移すのが現実的です。ただし`fragment-compose`の公開APIはComposable関数とKotlin拡張関数で構成されており、Javaからは呼べません。Java資産の画面を移すならKotlin化が前提になるため、着手前に[言語選定](/tech/details/15321/)の判断を済ませておく必要があります。移行先の全体像は[Jetpack Composeとは？宣言的UIの仕組みとBOM運用・採用判断を解説](/tech/details/16030/)にまとめています。

一方で、Fragmentを今すぐ捨てるべきとまでは言えません。Navigationコンポーネントの画面遷移はFragmentを目的地として扱う構成が現役で、ダイアログやマルチペインを含む既存画面の全面移行は工数に見合わないことが多いためです。判断の分かれ目は移行の工数ではなく、その画面をこの先も触り続けるかどうかです。

## よくある質問

### onCreateView、onAttach、onViewCreated、onStart、onCreateはどの順番で呼ばれますか？

onAttach、onCreate、onCreateView、onViewCreated、onStartの順です。onCreateはView生成前の初期化、onCreateViewはView生成そのものと役割が分かれており、名前が似ているだけで担当が違います。onCreateViewとonViewCreatedは連続して呼ばれ、その後onStartとの間にonViewStateRestoredが挟まります。

### onDestroyViewとonDestroyの違いは何ですか？

onDestroyViewはFragmentのViewだけが破棄されるときに呼ばれ、Fragmentのインスタンスは残ります。onDestroyはFragment自体が破棄されるときに呼ばれます。javadocはonDestroyViewをonStopの後、onDestroyの前と定めています。バックスタックに積んで別のFragmentへ置き換えたときはonDestroyViewまでしか進まないため、View参照の解放はonDestroyではなくonDestroyViewに書く必要があります。

### フラグメントとは何ですか？

Activityの中に埋め込んで使うUIの部品で、Activityとは別に自分自身のライフサイクルを持ちます。1つのActivityに複数配置でき、画面サイズに応じた出し分けや部分的な差し替えができます。単体では画面として起動できず、FragmentManagerによって状態が管理されます。現在の実装対象はandroidx.fragment.app.Fragmentで、OS標準のandroid.app.FragmentはAPI 28で非推奨になっています。

### onSaveInstanceStateはいつ呼ばれますか？

状態が保存される場面、つまり画面回転などの構成変更やプロセス終了の前に呼ばれます。onStopとの前後関係はAPIレベルで異なり、API 27以前はonStopの前、API 28以降はonStopの後です。加えてjavadocは「onDestroy()より前ならいつでも呼ばれ得る」と注意しており、バックスタックに積まれてViewを破棄済みのFragmentにも呼ばれます。逆に、バックスタックに積まずにremove()した場合やホストのActivityがfinishする場合は状態が保存されません。

### setRetainInstanceの代わりに何を使えばよいですか？

ViewModelです。androidxのFragment.javaのjavadocは、Fragment自体を保持するのではなく非保持のFragmentを使い、保持したい状態はそのFragmentに紐づくViewModelへ置くよう指示しています。ViewModelのコンストラクタが状態の生成、onCleared()が最終破棄の合図になります。プロセス終了もまたいで復元したい値は、ViewModel向けのSaved Stateモジュールを併用してください。

## 関連記事

- [Androidアプリ開発の言語はKotlinとJavaのどちらか？選定基準と環境まで解説](/tech/details/15321/)
- [Jetpack Composeとは？宣言的UIの仕組みとBOM運用・採用判断を解説](/tech/details/16030/)
- [Kotlin Coroutinesとは？suspendの仕組みと構造化並行性・採用判断](/tech/details/16036/)
- [WorkManagerとは？Androidの遅延実行の仕組みと採用判断を解説](/tech/details/16038/)
- [Android 17（API 37）正式リリース｜いつ・対応機種・ART/新機能を総まとめ【2026年6月】](/tech/details/10993/)

---

出典: [Fragmentのライフサイクル呼び出し順｜Javaで押さえる13コールバックと落とし穴](<https://www.issoh.co.jp/tech/details/4368/>)（株式会社一創）
