onCreate — その実際、AndroidでのActivity初期化

著者: IT Sectr 公開日: 2026-03-03 読了時間: 10 分

onCreateは、AndroidにおけるActivityおよびFragmentのライフサイクルで最初のだけでなく唯一の必須メソッドです。システムはコンポーネントを作成する際に一度だけこれを呼び出し、以前に保存された状態をもつBundleパラメータを渡します。onCreate内で、開発者はユーザーインターフェースを初期化し、View要素をバインドし、イベントハンドラーを構成し、savedInstanceStateからデータを復元します。正しいonCreateの実装なしでは、いかなるAndroidアプリケーションも起動できません — それは各画面へのエントリポイントです。一般的なActivityライフサイクルの詳細については、記事 Activity Lifecycle をお読みください。

ポイント

  • onCreate — 最初のだけでなく唯一の必須ライフサイクルメソッド。ActivityまたはFragmentを作成する際に一度だけ呼ばれる
  • Bundleパラメータ — savedInstanceStateには、onSaveInstanceStateで保存されたデータか、Activityが初めて作成される場合はnullが含まれる
  • setContentView — Activityに対するonCreate内での必須呼出し。XMLレイアウトをコードに結び付ける
  • UIの初期化 — findViewById、RecyclerViewアダプターの設定、クリックリスナーの設定 — onCreateの一般的なタスク
  • Fragment.onCreate — Activityとは異なる。ここではsetContentViewを呼ばず、レイアウトはonCreateViewを通じて渡す
  • 制限時間 — onCreateは5秒以内に完了する必要があり(ANRスレッショルド)、長時間の処理はバックグラウンドスレッドに移される
  • ViewModelとonCreate — onCreateでViewModelを初期化すると、画面回転でもデータが失われずに生き残る

AndroidでのonCreateとは

onCreateは、ActivityまたはFragmentの新しいインスタンスを作成する際にAndroidが呼び出すコールバックメソッドです。これはユーザー画面コードへの最初のエントリポイントです。onCreateが呼ばれる前には、いかなるユーザーコードも実行されません。システムは、メソッドにBundleパラメータを渡します。これには、以前に保存されたデータ(再作成時)か、null(初回起動時)が含まれます。

onCreateメソッドは、android.app.Activityクラスおよびandroidx.fragment.app.Fragmentクラスで定義されています。両方のバリエーションは、コンポーネントの初期化、UIの設定、状態復元といった似た仕事を実行します。しかし、具体的な実装は異なります — Activityはレイアウトを読み込むためにsetContentViewを使用し、FragmentはonCreateViewを通じてViewを返します。開発者はActivityで少なくともonCreateをオーバライドする必要があります — これがなければ、Androidは画面を表示できません。

onCreateは、Activityインスタンスの完全なライフサイクルで、廃止とまで一度だけ呼ばれます。画面回転時でも、新しいActivityインスタンスは、前のインスタンスからのBundleをもって、新しいonCreate呼出しを受け取ります。これにより、onCreateは一度だけの初期化に適した場所となります。データの読み込み、アダプターの作成、DaggerやHiltを使用したDIコンポーネントの設定などを行います。

ActivityでのonCreate

Activityにおいて、onCreateメソッドは4つの主なタスクを実行します。レイアウトマークアップの読み込み、View要素の初期化、Bundleからの状態復元、および主なイベントハンドラーの設定です。onCreateにおける必須最小限のコードは、super.onCreate(savedInstanceState)およびsetContentView(R.layout.activity_main)を呼ぶことです。

kotlin
class MainActivity : AppCompatActivity() {
    private var binding: ActivityMainBinding? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // ViewBinding — findViewByIdの現代的な代替品
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding?.root)

        // bindingを使用した初期化
        binding?.apply {
            welcomeText.text = getString(R.string.welcome)
            startButton.setOnClickListener { startGame() }
        }

        // 状態の復元
        if (savedInstanceState != null) {
            score = savedInstanceState.getInt("score", 0)
            binding?.scoreText?.text = score.toString()
        }
    }
}

現代の実践では、findViewByIdの代わりにViewBindingを使用します。ViewBindingは、コンパイル時にActivityMainBindingクラスを生成し、不正なIDによるエラーを排除し、ボイラプレートコードを減少します。Googleは、Android Studio 3.6以降、ActivityおよびFragmentでViewにアクセスする標準的な方法としてViewBindingを推奨しています。

onCreateでの操作の順序は廃止である必要があります。まずsuper、次にsetContentView、そしてその他のすべての操作を行います。setContentViewの前にfindViewByIdを呼ぶとnullが返されます — まだレイアウトが読み込まれておらず、View要素が階層構造に存在しないからです。これは、Android開発の初心者がよく犯す誤りの一つです。

FragmentでのonCreate

FragmentでのonCreateはActivityとは異なります。ここではsetContentViewを呼ばず、UIに関係しないデータの初期化のみが実行されます。Fragmentは、コンポーネントの作成とViewの作成を二つの独立したメソッドに分けています。onCreate(一度だけ呼ばれる)とonCreateView(Viewが作成または再作成されるたびに呼ばれる)です。

kotlin
class UserListFragment : Fragment() {
    private lateinit var viewModel: UserViewModel
    private var binding: FragmentUserListBinding? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // ViewModelの初期化 — Viewの再作成を超えて生き残る
        viewModel = ViewModelProvider(this)[UserViewModel::class.java]

        // FragmentManagerからの引数
        arguments?.let {
            viewModel.loadUser(it.getString("user_id") ?: "")
        }

        // 回転時の保存
        retainInstance = true
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        binding = FragmentUserListBinding.inflate(inflater, container, false)
        return binding!!.root
    }
}

ActivityとFragmentのonCreateの主な違いは次のとおりです。FragmentのonCreateには、Viewに関係するコードを含めてはなりません。なぜなら、Viewは破壊されて再作成されることがあり(ViewPagerのタブ切替時など)、onCreateは一度しか呼ばれないからです。データの読み込み、ViewModelの設定、アダプターの初期化はonCreateのタスクであり、ViewのバインドはonViewCreatedのタスクです。

savedInstanceStateと状態復元

onCreateの savedInstanceStateパラメータは、ActivityまたはFragmentの一時的な状態を保存および復元するためのメカニズムです。システムがActivityを破壊する際(画面回転、メモリ不足)、onSaveInstanceState()を呼び出し、開発者がBundleにキーバリューエントリを格納します。新しいインスタンスが作成されると、このBundleはonCreateで戻されます。

Bundleは、String、Integer、Boolean、Long、Float、Double、それらの配列、およびParcelableおよびSerializableオブジェクトといったデータ型をサポートしています。複雑なオブジェクトには、Parcelableを使用します — Android固有のより高性能なシリアライゼーションメカニズムです。Bundleのサイズは約500 KBに制限されています — 制限を超えるとTransactionTooLargeExceptionが発生します。

kotlin
companion object {
    private const val KEY_USER_NAME = "user_name"
    private const val KEY_SCORE = "score"
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_game)

    if (savedInstanceState != null) {
        userName = savedInstanceState.getString(KEY_USER_NAME) ?: ""
        currentScore = savedInstanceState.getInt(KEY_SCORE)
    }
}

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    outState.putString(KEY_USER_NAME, userName)
    outState.putInt(KEY_SCORE, currentScore)
}

理解すべき重要な点は次のとおりです。ユーザーがfinish()や戻るボタンでActivityを明示的に閉じる場合、onSaveInstanceStateは呼ばれません。システムは、ユーザーが意識的に作業を終了しており、状態を保存する必要がないとみなします。したがって、長期的なデータ保存にすべてをsavedInstanceStateに依存することはできません — Room、DataStore、またはSharedPreferencesを使用してください。

onCreateのタイミングと制限

onCreateはメイン(UI)スレッドで実行され、システムはActivityを画面に表示する前にその完了を待ちます。onCreateが5秒を超えると、システムはANR(Application Not Responding)ダイアログを表示し、ユーザーにアプリケーションを閉じるオプションを提供します。ネットワークからのデータ読み込みやデータベースからの読み取りなどの長時間の操作は、バックグラウンドスレッドに移す必要があります。

Google Android Performance (2025)の推奨によると、中身設備ではonCreateは1秒未満で完了する必要があります。これを達成するためには、おちゃの初期化(Kotlinのlazyデリゲート)を使用し、重いデータ読み込みをonResumeやコルーチンに延期し、あまり使用されないUIコンポーネントにViewStubを適用し、Android Vitalsを通じて起動時間をプロファイリングします。

kotlin
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    // おちゃの初期化 — オブジェクトは最初のアクセス時にのみ作成される
    val heavyData by lazy {
        HeavyDataLoader.load()
    }

    // lifecycleScopeを使用したバックグラウンドスレッドでのデータ読み込み
    lifecycleScope.launch(Dispatchers.IO) {
        val users = userDao.getAllUsers()
        withContext(Dispatchers.Main) {
            adapter.submitList(users)
        }
    }
}

プロファイリングツール: Android Studio Profiler(CPUタブ)は、各メソッドの正確な実行時間を表示します。Android Vitals(Google Play Console)では、「コールドスタート時間」メトリクをトラックできます — ActivityのonCreateが500 msを超えると、コンソールはこれをパフォーマンス問題としてマークします。IT Sectrでは、CIパイプラインで各Activityの起動時間を自動制御するためにMacrobenchmarkテストを使用しています。

ViewModelとonCreate

ViewModelは、画面回転を超えて生き残る必要のあるデータをonCreateで初期化する最も良い方法です。ViewModelはonCreateでViewModelProviderを通じて作成され、構成変更があっても自動的に保存されます。回転後にActivityが再作成されると、ViewModelはメモリに残ったままで、onCreateはデータの失われない同じViewModelを受け取ります。

kotlin
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_profile)

    // ViewModelは一度作成され、構成変更を超えて存続する
    val viewModel: ProfileViewModel =
        ViewModelProvider(this)[ProfileViewModel::class.java]

    // LiveDataの観察 — データが変わるとUIが自動的に更新される
    viewModel.user.observe(this) { user ->
        binding?.userName?.text = user.name
        binding?.userEmail?.text = user.email
    }

    // ViewModelが作成されたばかりの場合のデータ読み込み
    if (savedInstanceState == null) {
        viewModel.loadProfile(userId)
    }
}

ViewModel + LiveData/StateFlowの組み合わせは、Bundleへの手動保存なしで画面回転問題を解決します。ViewModelはデータをメモリに格納し、LiveDataは再作成時にActivityを自動的に再サブスクライブし、StateFlow(Kotlin Coroutinesから)はコルーチンサポートで反応性を追加します。これは、GoogleがGuide to App Architectureで推奨している標準アーキテクチャです。

onCreate使用時の一般的な誤り

経験ある開発者でさえ、onCreateでよくある誤りを犯します。よくある5つの問題とその回避法を見てみましょう。

setContentViewの前にViewを操作する

もっともよくある誤りは、setContentViewを呼ぶ前にfindViewByIdを使ってViewを検索しようとすることです。すべてのView要素はレイアウトインフレーションの時点で作成されるため、setContentViewの前にfindViewByIdを呼ぶとnullが返され、Viewを使用しようとするとNullPointerExceptionが発生します。解決策: 嚴密な順序で、まずsuper、次にsetContentView、その後findViewByIdまたはViewBindingを使用します。

長時間処理によるUIスレッドのブロック

ネットワークからのデータ読み込み、データベースからの読み取り、大きな配列の処理をonCreateで直接行うと、最初のフレームのレンダリングがブロックされます。ユーザーはonCreateが完了するまで黒い画面を見ることになり、アプリの速度感が損なわれます。解決策: 非同期操作には、lifecycleScope.launchを使用し、読み込みが完了するまでスケルトン(UI placeholder)を表示します。

savedInstanceStateの無視

画面回転時にBundleから状態を復元しない場合、ユーザーは保存されていない入力をすべて失います: フォームフィールドのテキスト、スクロール位置、選択中の項目などです。解決策: 状態損失の可能性が低いように思えても、常にonCreateでsavedInstanceState != nullを確認してデータを復元します。

アノニマスクラスによるメモリリーク

onCreate内のアノニマスクラスやラムダは、Activityが破壊された後も暗黙にActivityへの参照を保持することがあります。例えば、onCreateで作成されたHandlerは、Activityが破壊された後も遅延タスクを実行し続けます。解決策: LifecycleObserver、ViewModel、およびlifecycleScopeを使用します。これらは、破壊時に自動的にタスクをキャンセルします。

Fragment.onCreateでの過度な初期化

Fragment.onCreateでViewを初期化するのは論理的な誤りです。なぜなら、ViewはonCreateを呼ばずに再作成できるからです。onCreateでリスナーを設定し、onCreateViewでViewをバインドすると、再作成時にリスナーは古いViewに残ったままになります。解決策: すべてのView関連の仕事はonViewCreatedで実行し、onCreateはデータレイヤーの初期化のみに留めます。

よくある質問

ActivityでonCreateをオーバライドする必要はありますか?

はい、onCreateのオーバライドは必須です。ユーザーインターフェースを表示するいかなるActivityにとっても必要です。これがなければ、setContentViewを呼び出してXMLレイアウトを読み込むことができません。ActivityにUIがない場合(例えば、透明なActivityスタブ)でも、onCreateはオーバライドされますが、setContentViewは呼ばれません。

Activityを破壊せずにonCreateを再呼出しできますか?

いいえ、同じActivityインスタンスに対してonCreateを再呼出しすることはできません。Activityが破壊されて再作成された場合(画面回転、メモリ不足)、それは新しいインスタンスで、新しいonCreate呼出しが行われます。例外としてrecreate()メソッドがありますが、これはActivityを強制的に破壊して再作成するもので、新しいインスタンスの再作成です。

super.onCreateを呼ばなかった場合どうなりますか?

super.onCreate(savedInstanceState)を呼ばない場合、Android RuntimeはSuperNotCalledExceptionをスロークし、アプリケーションがクラッシュします。システムは、オーバライドされた各ライフサイクルメソッドがsuperバージョンを呼ぶことを嚴格に要求します — これにより、内部状態マシンが正常に動作することが保証されます。

ActivityのonCreateとFragmentのonCreateの違いは何ですか?

主な違いは次のとおりです。ActivityのonCreateはsetContentViewを通じてUIを読み込みますが、FragmentのonCreateはデータのみを初期化します。Fragmentは、別のメソッドonCreateViewでViewを作成します。これは複数回呼ぶことができ(例えばタブ切替時)、Fragment.onCreateはFragmentインスタンスの生存期間に一度しか呼ばれません。

onCreateから他のメソッドにデータを渡すにはどうすればよいですか?

onCreateで初期化されたデータはActivityまたはFragmentのクラスフィールドに格納されます。例えば、private lateinit var binding: ActivityMainBindingはクラスレベルで宣言され、onCreateで初期化され、その後のすべてのメソッドで使用できます。画面回転を超えて生き残る必要のあるデータには、LiveDataまたはStateFlowを使用したViewModelを使用します。

まとめ

  • onCreate — 必須のライフサイクルメソッド。ActivityまたはFragmentを作成する際に一度呼ばれる
  • setContentView — Activityに対する必須呼出し。XMLレイアウトを読み込む。Fragmentの場合、レイアウトはonCreateViewを通じて読み込まれる
  • savedInstanceState — 再作成時に保存された状態をもつBundle。初回起動時はnull
  • 制限時間 — onCreateは1秒未満で完了する必要があり、長時間の操作はコルーチンに移す
  • ViewModel — onCreateでViewModelを初期化すると、画面回転時のデータ失われ問題が解決される
  • Fragment vs Activity — Fragment.onCreateにはUIコードがなく、Activity.onCreateはsetContentViewでレイアウトを読み込む
  • 5つの一般的な誤り — setContentView前のView操作、UIブロック、Bundleの無視、メモリリーク、Fragment.onCreateでのUIコード

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください