2012年11月17日土曜日

回転時にActivityを破棄させない方法


こんにちは。scarvizです。

AndroidのActivityは、端末回転時に縦レイアウト、横レイアウトの切り替えをするために、
一度破棄し、再生成されますよね。

でも、別に縦横関係ないアプリだと、Activityの破棄は色々問題を抱えてしまいます。
スレッド立ててると一緒に破棄しちゃうので、ちょっと大丈夫なの?的な。

回転自体を固定するようにAndroidManifestで指定することも出来ますが、固定が必要ないアプリの場合は、いまいち感があります。

回転は許可して、回転されると困る場合にのみ、回転を一時的にブロックするような処理を入れても、見た目の回転はなくなりますが、Activityは再生成されてしまいます。

そこで、android:configChanges属性を使って対応する方法があります。





■android:configChanges属性
AndroidManifestのactivityタグにandroid:configChanges属性があります。
これは端末の状態が変更された場合に検出し、ハンドリングさせてくれるものです。
これを使えば、画面回転時に検出をし、自動でActivityを破棄していたところを、自分で回転時にどうするかの処理を決めることが出来ます。

android:configChanges属性の値にはどの場合に検出するかを指定してあげます。
値については下記を参照してください。
http://developer.android.com/guide/topics/manifest/activity-element.html

今回は画面回転時なので、"orientation"を指定します。
また、キーボードの引き出し時も同様なので、"keyboardHidden"を一緒に指定してあげるのが一般的なようです。
回転処理を検出したいActivityを定義しているactivityタグに、下記を記述してください。

 android:configChanges="orientation|keyboardHidden"

これを記載したActivityで回転をさせても、Activityは破棄されなくなります。
回転時に何か処理させたい場合は、onConfigurationChangedメソッドをオーバーライドして記述します。

さて、これでOKと思ったら、実はAPIレベル13(Android3.2)以上の場合は、これではダメなんです。
正確にはandroid:targetSdkVersionが13以上を指定している場合になります。


■APIレベル13以上での対応
APIレベル13から新たに"screenSize"という値が加わりました。
画面のサイズ変更時に検出できる値になります。
先と同様の処理を行いたい場合は、下記のように記述する必要があります。

 android:configChanges="orientation|screenSize"

詳細は下記を参照ください。
http://developer.android.com/guide/topics/resources/runtime-changes.html#HandlingTheChange

ただし、これはAPIレベル13以上で動作するアプリの場合です。


■APIレベル12以下も含むAPIレベル13以上での対応
たぶん、まだ多くの方は、APIレベル7または8(Android2.1または2.2)以上で動作させることを想定して開発されていると思います。
この場合は、そもそも"screenSize"が使えないので、APIレベル13以上の端末ではActivity破棄を止められません。

そこで、AndroidManifestのuses-sdkタグに、android:targetSdkVersion属性を12以下で指定することで対応します。

例えば下記のように、
 <uses-sdk
  android:minSdkVersion="8"
  android:targetSdkVersion="10" />

 <application
  ・・・>
  <activity
   android:configChanges="orientation|keyboardHidden"
   ・・・>
  </activity>
 </application>

とすれば、APIレベル8以上の端末にインストール可能ですが、動作はAPIレベル10(Android2.3.3または2.3.4)であわせるようになります。
なので、端末がAPIレベル13以上でも、回転時にActivity破棄を行わなくなります。


APIレベル13以上の端末を持っている人は気付くと思いますが、持っていない人は、android:targetSdkVersionも指定しないといけない事に気を付けないといけませんね。

0 件のコメント:

コメントを投稿