onStart:Android画面におけるActivityの可視性の本質

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

onStartは、ActivityまたはFragmentがユーザーに表示される際に呼び出されるAndroidライフサイクルメソッドです。この瞬間、画面がデバイスのディスプレイに表示されますが、onResumeが呼び出されるまで入力フォーカスがなく、まだユーザーと対話できません。onStartメソッドは、システムリスナーの登録、位置情報サービスへの接続、コンポーネントが画面に表示されている間動作するアニメーションの開始に最適です。完全なActivityライフサイクルの詳細については、記事Activity Lifecycleをご覧ください。

重要なポイント

  • onStart — ActivityまたはFragmentが画面に表示されるときに呼び出されます。onResumeの前に実行
  • リスナーの登録 — BroadcastReceiver、LocationListener、SensorListenerをonStartで登録し、onStopで解除
  • アニメーション — 画面が表示されている間動作するアニメーションを開始。onStopで一時停止
  • バインドサービス — onStartでbindServiceを介してクライアント-サーバーサービスに接続、onStopで切断
  • onStart vs onResume — onStart = 可視性、onResume = フォーカス+インタラクション。異なる画面アクティビティレベル
  • Fragment.onStart — Activity.onStartの後に呼び出され、Fragmentがコンテナ内で表示される
  • onStart/onStopペア — onStartで接続したリソースは、リーク防止のためonStopで必ず解放

AndroidにおけるonStartの本質

onStartはActivityライフサイクルの2番目のメソッドであり、システムによってonCreateの後(または停止状態から戻る場合はonRestartの後)に呼び出されます。onStartが呼び出された瞬間、ActivityまたはFragmentが画面に表示されます。ユーザーはインターフェースを表示できますが、画面はまだ対話の準備ができていません — 入力フォーカスはonResumeの後にのみ表示されます。

onStartメソッドはActivityの「可視ライフタイム」(visible lifetime) — onStartとonStopの間の期間に含まれます。この間、Activityは他のウィンドウ(透明なActivityやダイアログウィンドウなど)で部分的に覆われることがありますが、UIは引き続き表示されたままです。これは、Activityが完全な入力フォーカスを持つ「フォアグラウンドライフタイム」(onResume — onPause)とは異なります。

この3レベルの階層を理解することは、コードを適切に分散するために重要です。onCreate — 1回限りの初期化、onStart — 可視リソースの接続、onResume — 排他的リソースへの排他的アクセス。これらのレベルを混同する開発者は、画面切り替え時にメモリリークやアプリケーションの誤動作を引き起こすリスクがあります。

ActivityのonStart

Activityでは、画面がディスプレイに表示されるたびにonStartメソッドが呼び出されます — 最初の起動時(onCreate後)とバックグラウンドから戻る時(onRestart後)の両方です。onCreateとは異なり、onStartはActivityインスタンスの生存期間中に複数回呼び出される可能性があるため、画面が表示されるたびに実行する必要があるコードがここに配置されます。

kotlin
class DashboardActivity : AppCompatActivity() {
    private val connectivityReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            val isConnected = ... // ConnectivityManagerの確認
            binding?.statusIndicator?.setColor(
                if (isConnected) Color.GREEN else Color.RED
            )
        }
    }

    override fun onStart() {
        super.onStart()
        registerReceiver(
            connectivityReceiver,
            IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
        )
        SensorManager.getInstance().registerStepCounter()
    }

    override fun onStop() {
        unregisterReceiver(connectivityReceiver)
        SensorManager.getInstance().unregisterStepCounter()
        super.onStop()
    }
}

重要なルール:onStartで接続したすべてのリソースはonStopで解放する必要があります。これにより、Activityが画面から非表示になったときに、バッテリーを消費したり、システムイベントをリッスンしたり、メモリを占有したりしなくなります。Android Studioには、対応する登録解除なしでBroadcastReceiverを登録することを警告するlintルールが含まれています。

FragmentのonStart

FragmentのonStartは、ホストActivityのライフサイクルに密接に関連しています。Fragmentは、それを含むActivityがonStartを受け取った後にonStartを受け取ります。ただし、Fragmentが遅延モード(addToBackStackなしのFragmentTransaction.commit())で追加された場合、onStartは遅延して呼び出されることがあります。

kotlin
class MapFragment : Fragment() {
    private var mapView: MapView? = null

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        mapView = MapView(requireContext())
        return mapView!!
    }

    override fun onStart() {
        super.onStart()
        mapView?.onStart()
        LocationService.connect(requireContext())
    }

    override fun onStop() {
        mapView?.onStop()
        LocationService.disconnect()
        super.onStop()
    }
}

Fragment.onStartの特殊性:FragmentがoffscreenPageLimit = 1のViewPager内にある場合、隣接するフラグメントも表示される前にonStartを受け取ります。これにより、リスナーが早期に登録される可能性があります。このような場合は、setUserVisibleHint()メソッドを使用するか、onStart内でisVisibleをチェックして、実際に表示されているフラグメントに対してのみリスナーを登録します。

onStartとonResumeの違い

onStartとonResumeの主な違いは、画面アクティビティのレベルです。onStartはActivityが画面に表示されているが、必ずしもフォアグラウンドにあるわけではないことを示します。onResumeはActivityがフォアグラウンドにあり、入力フォーカスを持っていることを示します。この違いはダイアログウィンドウの例で示されます。Activityの上にDialogが表示されると、ActivityはonResumeを失います(onPauseが呼び出されます)が、表示されたままになります — onStart/onStopは呼び出されません。

比較表は、各メソッドがどのシナリオで呼び出されるかを明確に示しています:

シナリオonStartonResume
アプリ起動呼び出される呼び出される
Activity上にDialogが開かれる呼び出されないonPause(フォーカス喪失)
ホームボタンが押されるonStop(非表示)onPause → onStop
最近のアプリから戻るonStart(表示)onResume(フォーカス)
画面回転onCreate → onStart→ onResume
着信onStop(非表示)onPause → onStop

この表は、開発者が特定のコードをどのメソッドに配置するかを決定するのに役立ちます。たとえば、アプリが画面のオーバーラップ(ダイアログでも)の際にビデオ再生を一時停止する必要がある場合、コードはonPauseに配置されます。画面が完全に非表示になったときにのみビデオを停止する必要がある場合 — コードはonStopに配置されます。

リスナーとサービスの登録

onStartは、Activityが画面に表示されている間のみ動作するリスナーを登録するための最適な場所です。これは、システムイベント用のBroadcastReceiver、位置情報用のLocationListener、デバイスセンサー用のSensorListenerの3つの主要なシステムコンポーネントに関係します。

onStartでのBroadcastReceiver

BroadcastReceiverはonStartでContext.registerReceiver()を介して動的に登録され、onStopでunregisterReceiver()を介して登録解除されます。動的登録は、マニフェストでの静的登録よりも推奨されます。これは、レシーバーのライフタイムをActivityの可視期間に制限するためです — Activityが非表示の場合、アプリはシステムブロードキャストメッセージで起動しません。

kotlin
private val batteryReceiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent) {
        val level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
        binding?.batteryText?.text = "$level%"
    }
}

override fun onStart() {
    super.onStart()
    registerReceiver(batteryReceiver, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
}

override fun onStop() {
    unregisterReceiver(batteryReceiver)
    super.onStop()
}

LocationListenerとSensorListener

位置情報とセンサーはリソースを大量に消費する操作です。onStartでGPS更新を要求し、onStopでキャンセルすることで、画面が非表示のときにアプリがバッテリーを消費しないようにします。細かい調整には、最小間隔と距離を指定したrequestLocationUpdatesを使用します — たとえば、10秒と10メートル。これにより、精度と消費電力の最適なバランスが得られます。

アニメーションとonStart

onCreateではなくonStartでアニメーションを開始することで、画面が表示されるたびにアニメーションが開始されます。onCreateでアニメーションを開始すると、最初のActivity作成時のみ機能し、バックグラウンドから戻る時には機能しません。onStartはActivityが表示されるたびに呼び出されるため、循環アニメーションやトランジションを開始するのに最適な場所です。

kotlin
private lateinit var pulseAnimator: ValueAnimator

override fun onStart() {
    super.onStart()
    pulseAnimator.start()
    binding?.loadingIndicator?.animate()?.alpha(1f)?.start()
}

override fun onStop() {
    pulseAnimator.cancel()
    binding?.loadingIndicator?.animate()?.cancel()
    super.onStop()
}

ObjectAnimatorやValueAnimatorを使用するアニメーションでは、onStopでcancel()を呼び出すことが重要です。Activityが非表示になった後もアニメーションが実行され続けると、GPUとCPUのリソースを無駄に消費し、デバイスのパフォーマンスを低下させ、バッテリー消費を加速させます。Android Studio Profiler(GPUグラフ)を使用すると、アクティブなアニメーションを追跡し、リークを検出できます。

onStart/onStopのペアルールは、プレビュー用カメラ(CameraX)の操作にも適用されます。onStartでカメラを開き、onStopで閉じることで、アプリが画面に表示されていないときに他のアプリがカメラをブロックされないようにします。このルールの違反は、Google Playでネガティブなレビューの一般的な原因です。

よくある質問

リスナー登録におけるonStartとonResumeの違いは何ですか?

onStart — 画面が表示されている間動作するリスナー用(BroadcastReceiver、LocationListener、SensorListener)。onResume — 排他的アクセスが必要なリソース用(カメラ、ビデオキャプチャ、音声認識)。システムイベントリスナーは排他的アクセスを必要とせず、部分的なオーバーラップでも動作できるため、onStartで登録されます。カメラは完全なフォーカスがある場合にのみアクティブにする必要があるため、onResumeで開かれます。

onStartが呼び出されないことがありますか?

Activityが表示状態に移行する場合、onStartは常に呼び出されます。onStartなしの唯一のシナリオは、Activityが作成されてすぐに終了する場合です(たとえば、onCreateのエラーが原因)。この場合、onCreateの直後にonDestroyが呼び出されます。しかし、これは緊急シナリオであり、適切に記述されたコードでは発生するべきではありません。

onStartはonResumeなしで呼び出せますか?

はい、別のActivityまたは透明なウィンドウがActivityの上にすぐに開かれる場合、onStartはonResumeを受け取らないことがあります。たとえば、onCreateの後に認証画面が起動された場合(Activity A → Activity B)、Activity AではonStartが呼び出されますが、onResumeは呼び出されません — 画面Bに覆われるとすぐにonPause → onStopを受け取ります。

onStartは何回呼び出せますか?

onStartはActivityインスタンスの生存期間中に複数回呼び出される可能性があります。Activityが非表示状態(onStop)から表示状態に移行するたびに、onStartが呼び出されます。実際には、アプリを積極的に使用すると、onStartはセッション中に数十回または数百回呼び出されることがあります。

onStartでデータをロードすべきですか?

onStartでのデータロードは、画面が表示されるたびにデータを更新する必要がある場合に正当化されます。たとえば、ニュースフィードや通知リストなどです。ただし、ロードは非同期で行う必要があります — lifecycleScopeを使用したコルーチンを介して、UIスレッドをブロックしないようにします。画面表示の間で変更されないデータの場合は、onCreateで1回ロードするだけで十分です。

まとめ

  • onStart — 可視ライフタイムメソッド。ActivityまたはFragmentが画面に表示される際に呼び出される
  • onStartでの登録 — BroadcastReceiver、LocationListener、SensorListenerをonStartで登録、onStopで解除
  • onStart vs onResume — onStart = 可視性、onResume = 入力フォーカス。異なるリソースタイプに異なるレベル
  • アニメーション — 循環アニメーションをonStartで開始、onStopで停止。GPUリソースリークを防止
  • Fragment.onStart — Activity.onStartに連動。ViewPagerでは隣接フラグメントにも事前に呼び出される
  • ペアルール — すべてのonStartリソースはonStopで解放する必要がある。さもなければメモリとバッテリーのリーク
  • データロード — onStartでは、画面が表示されるたびに更新すべきデータをロードする

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

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

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

こちらもお読みください