WebViewを使っていると困ること
それが次の現象が発生することですね。
- 普通にページが読み込まれる
- 画面向きが横または縦に変わる
- 読み込みされたページが破棄される
- あたらしく同じページをリロード
これがデフォルトの動作になってます。
でもこの動作だと困る場面があったので、
ここでは 画面回転時にWebViewリロードを防ぐ方法 を紹介。
1つだけじゃなくて複数の方法があります。
方法1.AndroidManifest.xmlで制御するやり方
まずはAndroidManifest.xmlで制御する方法
端的には android:configChanges を設定すればOKです。
▼ android:configChanges の解説
android:configChanges
アクティビティで処理する設定変更のリストを指定します。実行時に設定の変更が発生すると、デフォルトではアクティビティはシャットダウンおよび再起動されますが、この属性で設定を宣言しておくと、アクティビティの再起動を防止できます。代わりに、アクティビティは実行中のままになり、アクティビティの onConfigurationChanged() メソッドが呼び出されます。
たとえば画面回転とか言語変更とか・・・そういった変更だとアクティビティが再起動されるのですが、この属性にリストで渡しておけば再起動を防止できます。
実際には次の内容を設定するだけです。
▼ cinfigChnages属性の値をこうする
1 |
android:configChanges="orientation|screenSize" |
▼ 実際のAndroidManifest.xmlでの設定例
1 2 3 4 |
<activity android:name=".MainActivity" android:configChanges="orientation|screenSize"> </activity> |
こういう風にActivityごとに設定すればOK。
実機(Galaxy)で試したらうまくいきました。画面回転したときに回転直前のページ内容がきっちり保持されています。動的に設定しなくていいなら、これが楽なはずです。
方法2.Activity#onCreateの最初1回だけリロード
2つめはコード的にリロードを防ぐ方法
ただし、次の制限があります。
- コードは新規実行される
もしページ読み込み時に実行されるコードだったり、読み込み後に実行されたコードがある場合、回転後にその結果は保持されない。
- 保持される内容は制限される
少なくもフォーム入力・選択欄の値などは保持される。ただし動的に追加された要素などは保持できない模様..
実をいうと、あんまり役に立たないかも
でも一応参考として載せておきます。
実際に試してみたコードはこういう感じです。
▼ Activity全体のコード例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
public class MainActivity extends AppCompatActivity { private WebView webView = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); webView = findViewById(R.id.webview); /// 初回1回のみページ読みこみ if (savedInstanceState == null) { webView.loadUrl("file:///android_asset/index.html"); } } /// オーバーライドが必要 @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); } /// オーバーライドが必要 @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); webView.saveState(outState); } /// オーバーライドが必要 @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); webView.restoreState(savedInstanceState); } } |
実機で試したところ・・・動的に追加した要素が保持されなかったり、読み込み時に再度JSコードが実行されたり、期待する動作にはなりません。(+_+)
まあ限定的な場面では役に立つかもです。
まとめ : WebViewのリロードを防ぐには...
ここでは2つの方法を紹介しました。
- AndroidManifest.xmlで制御
各アクティビティに対して android:configChanges="orientation|screenSize" を設定すれば。画面回転時と画面サイズ変更時に再読み込みをさせなくできる。
- 最初の1回だけリロード
状態が変更されるたびにWebViewの状態を保存・復元する。そしてActivity#onCreateでは最初の1回だけ読み込みさせる。あまりいい方法ではない・・・
確実にやるなら1番めが圧倒的おすすめです。
ではまた($・・)/~~~