onRestart — AndroidのActivityライフサイクルのメソッドで、システムによってActivityがStopped状態からStarted状態に戻る前に呼び出されます。onRestartは、以前に別の画面で非表示にされたり、バックグラウンドに最小化されたりしたActivityが、再びユーザーに表示されるようになることを通知します。onRestartでは、開発者は古いデータを更新し、リストを再読み込みし、Activityが非表示の間に変更された可能性のあるUI状態を復元します。Google Android Vitals(2025)によると、onRestartを使用してデータを更新するアプリは、画面に戻ったときに情報が誤って表示されるケースが25%少なくなります。Android Developersドキュメントは、onRestartをActivityが再び画面に表示される前の準備段階として説明しています。
重要なポイント
onRestart — AndroidがonStartの直前に、Activityが非表示のStopped状態から表示状態に戻るときに呼び出すコールバックメソッドです。このメソッドは、Activityが再表示されるときにのみ呼び出される点でユニークです — インスタンスの最初の作成時には、シーケンスはonCreateから始まり、onRestartをスキップします。完全なサイクル:onCreate → onStart → onResume(初回起動)またはonRestart → onStart → onResume(以降の表示)。
Androidシステムの観点から見ると、onRestartはActivityが戻る準備をするための最適化です:リポジトリからデータを更新し、UI状態を同期し、ネットワーク接続を確認します。フォーカスを得るたびに呼び出されるonResume(ダイアログやシステムメニューから戻る場合も含む)とは異なり、onRestartは完全な非表示・復帰サイクルの間のみトリガーされます。これにより、onRestartは部分的なフォーカス損失時に不要な“重い”更新操作に最適な場所となります。
Android Activityライフサイクルの仕様によると、onStopとonRestartの間の時間間隔は、数秒(ユーザーが素早く切り替えた場合)から数時間(アプリがバックグラウンドにあり、ユーザーが戻ってきた場合)まで及ぶ可能性があります。この間に、リモートソース(API、DB)のデータが変更されている可能性があるため、onRestartは最新状態を確認するための自然なポイントです。
onRestartは、ActivityがStopped状態から戻るときにのみ呼び出されます。ActivityはonStopが呼び出された後にこの状態になります。以下に、onRestartにつながるすべてのシナリオを示します。
onRestart呼び出しのシナリオ:
onRestartが呼び出されない場合:画面回転時(Activityは破棄され、onCreateを介して再作成される)、ダイアログボックスから戻る場合(ActivityはonStopに入らず、onPause → onResumeのみ)、プロセス終了時(Activityは再作成される)。
onRestartとonCreateは、Activityを復元するための2つの異なるアプローチです。どちらを選ぶかは、Activityが完全に破棄されたか、単に非表示にされたかによって異なります。
| 特性 | onRestart | onCreate |
|---|---|---|
| 呼び出しタイミング | ActivityがStoppedから戻る | Activityが初めて作成されるか、破棄された後 |
| 状態の保持 | はい — ViewModelとフィールドは生存 | いいえ — すべて新しく作成される |
| Bundle | 渡されない | 渡される(savedInstanceState) |
| 典型的な処理 | データ更新、UIリフレッシュ | Viewの初期化、LiveDataの購読 |
| 呼び出し頻度 | 戻るたびに | 一度、または破棄後 |
選択ルール:Viewの初期化とLiveData/StateFlowの購読はonCreateで行います(Fragmentの場合はonViewCreated)。データ更新、リストの再読み込み、状態の確認はonRestartで行います。ViewModelを介してデータが読み込まれる場合、onRestartは単にViewModelのrefresh()メソッドを呼び出せばよく、Viewはリアクティブストリームを介して更新されたデータを購読します。
Googleの推奨:onRestartでonCreateのロジックを複製しないでください。ViewModelに現在のデータを読み込むrefresh()メソッドを抽出し、onRestartでそれらを呼び出します。これにより、クリーンなMVVMアーキテクチャが維持され、コードの重複が排除されます。
onRestartは、画面に戻るたびに実行されるべきだが、最初の開封時には不要な操作に最適な場所です。以下に典型的なシナリオを示します:
viewModel.refreshItems()を呼び出します。onRestartでやってはいけないこと:Viewを再初期化しないでください — Activityが破棄されていないため、それらは生存しています。LiveDataに再購読しないでください — onCreateでの購読はまだ有効です。新しいFragmentを作成しないでください — それらはすでにFragmentManagerに存在します。
最も重要な例外:アプリのプロセスがシステムによって強制終了された場合、onRestartは呼び出されません。これは、状態復元をonRestartに依存する際に開発者が見落としがちな重要なポイントです。
プロセス終了時:
これから保護する方法:重要な状態は常にonSaveInstanceState(Bundle)(onStopの前に呼び出される)に保存するか、ViewModelでSavedStateHandleを使用します。onCreateでsavedInstanceStateを確認します:nullでない場合はBundleから状態を復元し、nullの場合は新しいデータを読み込みます。
Google Android Vitalsによると、バックグラウンドでの長時間経過後のActivityへの復帰の約7%がプロセス終了後に発生します。これは、onRestartを呼び出すべきだったActivityの15回に1回が、実際にはonCreateを通過することを意味します。このシナリオを無視することは、“復帰後の空画面”バグの主な原因の1つです。
Activityは、編集画面から戻った後にタスクリストを更新するために、onRestartでviewModel.refreshTasks()を呼び出します。
class TaskListActivity : AppCompatActivity() {
private val viewModel: TaskViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_task_list)
viewModel.tasks.observe(this) { tasks ->
Log.d("TaskList", "${tasks.size}件のタスクを受信しました")
}
}
override fun onRestart() {
super.onRestart()
Log.d("TaskList", "onRestart: タスクリストを更新中")
viewModel.refreshTasks()
}
}
class TaskViewModel : ViewModel() {
private val _tasks = MutableLiveData<List<Task>>()
val tasks: LiveData<List<Task>> get() = _tasks
fun refreshTasks() {
viewModelScope.launch {
_tasks.value = TaskRepository().getAllTasks()
}
}
}
ViewModel.refreshTasks()はリポジトリから現在のデータを読み込みます。LiveDataは自動的にActivityにデータ変更を通知します — UIは追加のコードなしで更新されます。onRestartは新しい購読を作成しません — それはすでにonCreateで設定されています。
Activityは復帰時にトークンの有効性を確認し、必要に応じてログインにリダイレクトします。
class ProfileActivity : AppCompatActivity() {
private val authManager = AuthManager()
private val launcher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { Log.d("Profile", "ログイン画面から戻りました") }
override fun onRestart() {
super.onRestart()
if (!authManager.isTokenValid()) {
Log.d("Profile", "トークン期限切れ — ログインにリダイレクト")
launcher.launch(Intent(this, LoginActivity::class.java))
}
}
}
class AuthManager {
fun isTokenValid(): Boolean {
val expiry = SharedPreferencesManager().getTokenExpiry()
return System.currentTimeMillis() < expiry
}
}
ユーザーがアプリを長期間最小化し、トークンの有効期限が切れた後に戻ってきた場合、onRestartはログイン画面にリダイレクトします。これにより、期限切れのトークンでリクエストを試みたときのAPIエラーを防ぎます。注:確認はonResumeではなくonRestartにあります。これにより、ダイアログから戻るときの不要な確認を回避します。
Fragmentは、データを更新するためにLifecycleObserverを介してonRestartを使用します。
class FeedFragment : Fragment() {
private val viewModel: FeedViewModel by viewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewLifecycleOwner.lifecycle.addObserver(object : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_RESTART)
fun onRestart() {
Log.d("FeedFragment", "LifecycleObserverによるonRestart")
viewModel.refreshFeed()
}
})
}
}
FragmentでonRestartをオーバーライドする代わりに、LifecycleObserverが使用されます — 継承なしでライフサイクルイベントロジックを追加できる、より柔軟なアプローチです。ViewLifecycleOwnerは、observerがViewのスコープ内で生存することを保証します(onDestroyViewを超えて生存しません)。
よくある質問
onResumeは、Activityがフォーカスを得るたびに呼び出されます — ダイアログやシステムメニューから戻る場合も含みます(ActivityはonStopに入りませんでした)。onRestartは、Activityが完全に非表示にされていたStopped状態から戻るときにのみ呼び出されます。onRestartは“重い”更新のためのより限定的なイベントであり、onResumeは軽い操作(タイトルの変更、時刻の更新)のためのものです。
いいえ、できません。onRestartはonStopと対になるメソッドです:onRestartは、ActivityがonStopを通過した後にのみ呼び出されます。ActivityがonStopに入らなかった場合(例:ダイアログボックスが開かれた)、復帰時にonRestartは呼び出されず、onResumeのみが呼び出されます。
エミュレーターでHome(ホームボタン)を押します — Activityが最小化され、onStopを受け取ります。次に、最近のアプリまたはランチャーからアプリを開きます — ActivityはonRestart → onStart → onResumeを受け取ります。デバッグには、onRestartにブレークポイントを設定したDebug、またはActivityタグ付きのLog.dを使用します。
onRestartでのキャッチされない例外はForce Closeを引き起こします。システムはライフサイクルコールバックの例外をキャッチしません。onRestartで例外をスローする可能性のある操作(try-catchなしのネットワークリクエスト、nullのViewの操作)を実行する場合は、try-catchでラップしてください。
いいえ。onRestartは、Stopped状態から戻ってくる生存しているActivityに対してのみ呼び出されます。onRestartでのisFinishing()は常にfalseになります。isFinishing()の確認は、onPause(データ保存)とonDestroy(再作成と終了の区別)で意味があります。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。