11
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Android - Activity / Fragmentの再生成パターンと解決策

Posted at

概要

Androiderの方には当たり前のことかもしれないですが、、
AndroidでActivityの再生成について調べた際の知見をまとめます。
「Activity 再生成」などで検索するとたくさん有益な情報が出て来るので、合わせて調べていただけるといいと思います。
またFragmentについても少し言及したいと思っています。

結論

基本的に Activity/Fragmentは破棄されるもの。破棄されたとしても、適切に復帰できるような設計、コードを書いておくことが大事

個人的にはAndroid Architecture Componentをおすすめしたい

という記事です。

Activity再生成のパターン

  1. メモリ不足の際のOSトリガーによる再起動
  2. アクティビティで処理する設定の変更 (画面回転含む)

基本的には、大きく分けて上記2つなのかなと思っています。以下の2つのリンクを参考にしています。

解決策 (リスト)

アクティビティで処理する設定の変更

アクティビティで処理する設定変更のリストを指定します。実行時に設定の変更が発生すると、デフォルトではアクティビティはシャットダウンおよび再起動されますが、この属性で設定を宣言しておくと、アクティビティの再起動を防止できます。 代わりに、アクティビティは実行中のままになり、アクティビティの onConfigurationChanged() メソッドが呼び出されます。

これは、Activityの属性に以下を設定することで回避することが可能です。

android:configChanges="orientation|...|..."

設定リストはandroid:configChangesを参考にしてください。

Activity/Fragmentの状態復帰

簡単なデータであればBundleに入れて保存しておくのがよいと思われます。方法は2つあって、

  1. Intent / Arguments に含める
  2. onSaveInstanceState(), onRestoreInstanceState()で復帰する

Activityの起動時にIntentにデータを含める

以下のようにして、起動時にActivityに対してデータを送信しておくと再生成時にもデータは保持されます。

companion object {
  fun createIntent(context: Context): Intent {
    val intent = Intent(context, MyActivity::class.java)
    intent.putExtra(...)
    // ...
  }
}

Fragmentの起動時にArgumentsにデータを含める

こちらは、IntentのFragment版という感じで、同じようにBundleを含めます。

companion object {
  fun newInstance(context: Context): MyFragment {
    val f = MyFragment()
    val args = Bundle().apply {
      putInt("num", 1)
      // ...
    }
    f.setArguments(args)
    return f
  }
}

onSaveInstanceState, onSaveInstanceState

Activity, Fragmentどちらも使えます!!

override fun onSaveInstanceState(outState: Bundle?) {
  super.onSaveInstanceState(outState)
  // 保存しておきたい値を保存する...
}

  override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
    super.onRestoreInstanceState(savedInstanceState)
    // 保存しておいた値から値を取得...
  }

Fragment#setRetainInstanceを使う

Fragment限定です。いくつか問題があるみたいなので、注意が必要です。詳しくはこちら → Activity/Fragmentの再生成と画面回転に関するまとめ - Qiita

また、Activityが再生成された際はActivityがnullになるので getActivity() などに依存している場合は注意が必要です。その場合はListenerやCallbackなどを定義するといいと思います。(今回は再生成にはあまり関係ないので割愛します)

Fragment#setRetainInstance

Android Architecture Componentsを使う

Android Architecture Components | Android Developers
Now 1.0 stable

Googleがこれらの問題を解決するフレームワークを発表しましたね。自分も使ってみましたが、非常に使いやすいものでした。 こちらは、Activity, Fragmentのライフサイクルとは別に生きているため上にあげたものを気にする必要がなくなりました!
Android Architecture Componentsに関しては、たくさん記事があるのでそちらに譲らせていただきます。

参考

11
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?