onCreateは、AndroidにおけるActivityおよびFragmentのライフサイクルで最初のだけでなく唯一の必須メソッドです。システムはコンポーネントを作成する際に一度だけこれを呼び出し、以前に保存された状態をもつBundleパラメータを渡します。onCreate内で、開発者はユーザーインターフェースを初期化し、View要素をバインドし、イベントハンドラーを構成し、savedInstanceStateからデータを復元します。正しいonCreateの実装なしでは、いかなるAndroidアプリケーションも起動できません — それは各画面へのエントリポイントです。一般的なActivityライフサイクルの詳細については、記事 Activity Lifecycle をお読みください。
ポイント
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メソッドは4つの主なタスクを実行します。レイアウトマークアップの読み込み、View要素の初期化、Bundleからの状態復元、および主なイベントハンドラーの設定です。onCreateにおける必須最小限のコードは、super.onCreate(savedInstanceState)およびsetContentView(R.layout.activity_main)を呼ぶことです。
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はActivityとは異なります。ここではsetContentViewを呼ばず、UIに関係しないデータの初期化のみが実行されます。Fragmentは、コンポーネントの作成とViewの作成を二つの独立したメソッドに分けています。onCreate(一度だけ呼ばれる)とonCreateView(Viewが作成または再作成されるたびに呼ばれる)です。
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のタスクです。
onCreateの savedInstanceStateパラメータは、ActivityまたはFragmentの一時的な状態を保存および復元するためのメカニズムです。システムがActivityを破壊する際(画面回転、メモリ不足)、onSaveInstanceState()を呼び出し、開発者がBundleにキーバリューエントリを格納します。新しいインスタンスが作成されると、このBundleはonCreateで戻されます。
Bundleは、String、Integer、Boolean、Long、Float、Double、それらの配列、およびParcelableおよびSerializableオブジェクトといったデータ型をサポートしています。複雑なオブジェクトには、Parcelableを使用します — Android固有のより高性能なシリアライゼーションメカニズムです。Bundleのサイズは約500 KBに制限されています — 制限を超えるとTransactionTooLargeExceptionが発生します。
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はメイン(UI)スレッドで実行され、システムはActivityを画面に表示する前にその完了を待ちます。onCreateが5秒を超えると、システムはANR(Application Not Responding)ダイアログを表示し、ユーザーにアプリケーションを閉じるオプションを提供します。ネットワークからのデータ読み込みやデータベースからの読み取りなどの長時間の操作は、バックグラウンドスレッドに移す必要があります。
Google Android Performance (2025)の推奨によると、中身設備ではonCreateは1秒未満で完了する必要があります。これを達成するためには、おちゃの初期化(Kotlinのlazyデリゲート)を使用し、重いデータ読み込みをonResumeやコルーチンに延期し、あまり使用されないUIコンポーネントにViewStubを適用し、Android Vitalsを通じて起動時間をプロファイリングします。
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でViewModelProviderを通じて作成され、構成変更があっても自動的に保存されます。回転後にActivityが再作成されると、ViewModelはメモリに残ったままで、onCreateはデータの失われない同じViewModelを受け取ります。
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でよくある誤りを犯します。よくある5つの問題とその回避法を見てみましょう。
もっともよくある誤りは、setContentViewを呼ぶ前にfindViewByIdを使ってViewを検索しようとすることです。すべてのView要素はレイアウトインフレーションの時点で作成されるため、setContentViewの前にfindViewByIdを呼ぶとnullが返され、Viewを使用しようとするとNullPointerExceptionが発生します。解決策: 嚴密な順序で、まずsuper、次にsetContentView、その後findViewByIdまたはViewBindingを使用します。
ネットワークからのデータ読み込み、データベースからの読み取り、大きな配列の処理をonCreateで直接行うと、最初のフレームのレンダリングがブロックされます。ユーザーはonCreateが完了するまで黒い画面を見ることになり、アプリの速度感が損なわれます。解決策: 非同期操作には、lifecycleScope.launchを使用し、読み込みが完了するまでスケルトン(UI placeholder)を表示します。
画面回転時にBundleから状態を復元しない場合、ユーザーは保存されていない入力をすべて失います: フォームフィールドのテキスト、スクロール位置、選択中の項目などです。解決策: 状態損失の可能性が低いように思えても、常にonCreateでsavedInstanceState != nullを確認してデータを復元します。
onCreate内のアノニマスクラスやラムダは、Activityが破壊された後も暗黙にActivityへの参照を保持することがあります。例えば、onCreateで作成されたHandlerは、Activityが破壊された後も遅延タスクを実行し続けます。解決策: LifecycleObserver、ViewModel、およびlifecycleScopeを使用します。これらは、破壊時に自動的にタスクをキャンセルします。
Fragment.onCreateでViewを初期化するのは論理的な誤りです。なぜなら、ViewはonCreateを呼ばずに再作成できるからです。onCreateでリスナーを設定し、onCreateViewでViewをバインドすると、再作成時にリスナーは古いViewに残ったままになります。解決策: すべてのView関連の仕事はonViewCreatedで実行し、onCreateはデータレイヤーの初期化のみに留めます。
よくある質問
はい、onCreateのオーバライドは必須です。ユーザーインターフェースを表示するいかなるActivityにとっても必要です。これがなければ、setContentViewを呼び出してXMLレイアウトを読み込むことができません。ActivityにUIがない場合(例えば、透明なActivityスタブ)でも、onCreateはオーバライドされますが、setContentViewは呼ばれません。
いいえ、同じActivityインスタンスに対してonCreateを再呼出しすることはできません。Activityが破壊されて再作成された場合(画面回転、メモリ不足)、それは新しいインスタンスで、新しいonCreate呼出しが行われます。例外としてrecreate()メソッドがありますが、これはActivityを強制的に破壊して再作成するもので、新しいインスタンスの再作成です。
super.onCreate(savedInstanceState)を呼ばない場合、Android RuntimeはSuperNotCalledExceptionをスロークし、アプリケーションがクラッシュします。システムは、オーバライドされた各ライフサイクルメソッドがsuperバージョンを呼ぶことを嚴格に要求します — これにより、内部状態マシンが正常に動作することが保証されます。
主な違いは次のとおりです。ActivityのonCreateはsetContentViewを通じてUIを読み込みますが、FragmentのonCreateはデータのみを初期化します。Fragmentは、別のメソッドonCreateViewでViewを作成します。これは複数回呼ぶことができ(例えばタブ切替時)、Fragment.onCreateはFragmentインスタンスの生存期間に一度しか呼ばれません。
onCreateで初期化されたデータはActivityまたはFragmentのクラスフィールドに格納されます。例えば、private lateinit var binding: ActivityMainBindingはクラスレベルで宣言され、onCreateで初期化され、その後のすべてのメソッドで使用できます。画面回転を超えて生き残る必要のあるデータには、LiveDataまたはStateFlowを使用したViewModelを使用します。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。