Activity縦横切り替えの件

10620 ワード

Activityのライフサイクルは、Android開発者一人一人が理解しなければならない知識です.Activityは4つのコンポーネントの1つであり、最も頻繁に使用されるコンポーネントです.縦画面切り替えはAndroid開発者一人一人が直面する問題です.では、縦画面切り替え後のActivityではいったい何が起こっているのでしょうか.
1、ライフサイクルの変化
Activityを作成し、すべてのライフサイクルメソッドを書き換え、これらのメソッドにログを追加します.
public class ActivityA extends Activity {

   @Override
   protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.test_layout);
     Log.i("axe.mg","onCreate()");
   }

   @Override
   protected void onRestart() {
     super.onRestart();
     Log.i("axe.mg","onRestart()");
   }

   @Override
   protected void onStart() {
     super.onStart();
     Log.i("axe.mg","onStart()");
   }

   @Override
   protected void onResume() {
     super.onResume();
     Log.i("axe.mg","onResume()");
   }

   @Override
   protected void onPause() {
     super.onPause();
     Log.i("axe.mg","onPause()");
   }

   @Override
   protected void onStop() {
     super.onStop();
     Log.i("axe.mg","onStop()");
   }

   @Override
   protected void onDestroy() {
     super.onDestroy();
     Log.i("axe.mg","onDestroy()");
   }
}

このActivityを正常に起動します.
09-28 23:16:49.809 24348-24348/com.mg.axe.androiddevelop I/axe.mg: onCreate()
09-28 23:16:49.809 24348-24348/com.mg.axe.androiddevelop I/axe.mg: onStart()
09-28 23:16:49.819 24348-24348/com.mg.axe.androiddevelop I/axe.mg: onResume()

LogでActivityの作成からプレゼンテーションまでのライフサイクルを見ることができます:onCreate()--->onStart()--->onResume()
縦画面切り替えを行います.
09-28 23:17:42.519 24348-24348/com.mg.axe.androiddevelop I/axe.mg: onPause()
09-28 23:17:42.519 24348-24348/com.mg.axe.androiddevelop I/axe.mg: onStop()
09-28 23:17:42.519 24348-24348/com.mg.axe.androiddevelop I/axe.mg: onDestroy()

09-28 23:17:42.719 24348-24348/com.mg.axe.androiddevelop I/axe.mg: onCreate()
09-28 23:17:42.729 24348-24348/com.mg.axe.androiddevelop I/axe.mg: onStart()
09-28 23:17:42.729 24348-24348/com.mg.axe.androiddevelop I/axe.mg: onResume()

Logによってライフサイクルを2つの部分に分けて分析する:1、Activity破棄:onPause()--->onStop()--->onDestroy()2、Activityの再作成展示:onCreate()--->onStart()--->onResume()
結論:Activity縦画面切り替え時.Activityは再作成されます.縦画面切り替え時にActivityは破棄され、onPause()onStop()onDestory()が呼び出されます.Activityが再作成され、onCreate()onStart()onResume()が呼び出されます.
--
2、縦画面切り替え後のデータ復旧
Activityの縦画面切り替え時にActivityが再作成されることがわかっています.では、再構築前のデータをどのように復元しますか?Activityには、Activityの再構築前のデータを保存および復元する2つの方法があります.
  @Override
  protected void onSaveInstanceState(Bundle outState) {
     super.onSaveInstanceState(outState);
  }

  @Override
  protected void onRestoreInstanceState(Bundle savedInstanceState) {
     super.onRestoreInstanceState(savedInstanceState);
  }

onSaveInstanceState:縦画面切り替えの場合、Activity破棄前にonSaveInstanceStateがBundleパラメータを保存して現在のActivityのデータを保存するように呼び出されます.このメソッドはonStopの前に呼び出されます.
onRestoreInstanceState:Activityが再作成されるとonRestoreInstanceStateが呼び出され、Activityが破棄されるとonSaveInstanceStateメソッドで保持されたデータがBundleパラメータとしてonRestoreInstanceStateメソッドとonCreateメソッドに同時に渡されます.したがって、onRestoreInstanceStateとonCreateメソッドでは、同じパラメータBundle savedInstanceStateの2つを見ることができます.このメソッドはonStart後に呼び出されます.
この2つのメソッドが呼び出されるのは、Activity例外の場合に終了(たとえば、縦画面切り替え)される必要があることを強調します.
コード検証:ActivityでonSaveInstanceStateとonRestoreInstanceStateを書き換え、Activity再構築前のデータを保存および復元します.
onSaveInstanceStateに「value_string」のstringを保存し、onRestoreInstanceStateで「value_string」という値を取得します.
public class ActivityA extends Activity {

   @Override
   protected void onSaveInstanceState(Bundle outState) {
     super.onSaveInstanceState(outState);
     outState.putString("key","value_string");
     Log.i("axe.mg","onSaveInstanceState");
   }

   @Override
   protected void onRestoreInstanceState(Bundle savedInstanceState) {
     super.onRestoreInstanceState(savedInstanceState);
     String str =   savedInstanceState.getString("key");
     Log.i("axe.mg","onRestoreInstanceState");Log.i("axe.mg","get value:"+str);
   }

   @Override
   protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.test_layout);
     Log.i("axe.mg","onCreate()");
   }

   @Override
   protected void onRestart() {
     super.onRestart();
     Log.i("axe.mg","onRestart");
   }

   @Override
   protected void onStart() {
     super.onStart();
     Log.i("axe.mg","onStart()");
   }

   @Override
   protected void onResume() {
     super.onResume();
     Log.i("axe.mg","onResume()");
   }

   @Override
   protected void onPause() {
     super.onPause();
     Log.i("axe.mg","onPause()");
   }

   @Override
   protected void onStop() {
     super.onStop();
     Log.i("axe.mg","onStop()");
   }

   @Override
   protected void onDestroy() {
     super.onDestroy();
     Log.i("axe.mg","onDestroy()");
   }

縦横に表示されたログを取得します.
09-29 00:26:25.439 27568-27568/com.mg.axe.androiddevelop I/axe.mg: onPause()
09-29 00:26:25.439 27568-27568/com.mg.axe.androiddevelop I/axe.mg: onSaveInstanceState
09-29 00:26:25.439 27568-27568/com.mg.axe.androiddevelop I/axe.mg: onStop()
09-29 00:26:25.439 27568-27568/com.mg.axe.androiddevelop I/axe.mg: onDestroy()

09-29 00:26:25.499 27568-27568/com.mg.axe.androiddevelop I/axe.mg: onCreate()
09-29 00:26:25.499 27568-27568/com.mg.axe.androiddevelop I/axe.mg: onStart()
09-29 00:26:25.499 27568-27568/com.mg.axe.androiddevelop I/axe.mg: onRestoreInstanceState
09-29 00:26:25.499 27568-27568/com.mg.axe.androiddevelop I/axe.mg: get value:value_string
09-29 00:26:25.499 27568-27568/com.mg.axe.androiddevelop I/axe.mg: onResume()

Logによる分析:1、Activity破棄、onSaveInstanceState呼び出し、onSaveInstanceStateメソッドでoutState.putString("key","value_string");「value_string」という値が保存されています.
2、Activity再構築、onRestoreInstanceStateを呼び出し、onSaveInstanceStateメソッドでsavedInstanceStateを通過する.getString("key");「value_string」という値が取得されました.
3、縦画面切り替え時のActivity再構築を防止する方法
開発中に縦画面切り替え後のActivity再構築は望ましくないかもしれません.configChangeパラメータを設定する必要があります.android:configChanges=「orientation|screenSize」を設定できます.

     
       
       
   


配置追加android:configChanges="orientation|screenSize"(frameworkレイヤコードを追跡するのは、googleがandroid 3.2にscreensize変更の通知を追加したためであり、画面を回すときにorientationが変更されただけでなくscreensizeも変更されたので"screenSize"を追加する)この場合は縦横画面切り替え後にActivityは再構築されない.次のメソッドも呼び出されます.
@Override
public void onConfigurationChanged(Configuration newConfig) {
 super.onConfigurationChanged(newConfig);
}

コード検証:Activityによるandroidの追加:configChanges="orientation|screenSize"

     
       
       
   

public class ActivityA extends Activity {

  @Override
  public void onConfigurationChanged(Configuration newConfig) {
     super.onConfigurationChanged(newConfig);
     Log.i("axe.mg","onConfigurationChanged");
  }

   @Override
   protected void onSaveInstanceState(Bundle outState) {
     super.onSaveInstanceState(outState);
     outState.putString("key","value_string");
     Log.i("axe.mg","onSaveInstanceState");
   }

   @Override
   protected void onRestoreInstanceState(Bundle savedInstanceState) {
     super.onRestoreInstanceState(savedInstanceState);
     String str =   savedInstanceState.getString("key");
     Log.i("axe.mg","onRestoreInstanceState");Log.i("axe.mg","get value:"+str);
   }

   @Override
   protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.test_layout);
     Log.i("axe.mg","onCreate()");
   }

   @Override
   protected void onRestart() {
     super.onRestart();
     Log.i("axe.mg","onRestart");
   }

   @Override
   protected void onStart() {
     super.onStart();
     Log.i("axe.mg","onStart()");
   }

   @Override
   protected void onResume() {
     super.onResume();
     Log.i("axe.mg","onResume()");
   }

   @Override
   protected void onPause() {
     super.onPause();
     Log.i("axe.mg","onPause()");
   }

   @Override
   protected void onStop() {
     super.onStop();
     Log.i("axe.mg","onStop()");
   }

   @Override
   protected void onDestroy() {
     super.onDestroy();
     Log.i("axe.mg","onDestroy()");
   }

縦横に切り替えた後:
09-29 00:54:00.849 21338-21338/com.mg.axe.androiddevelop I/axe.mg: onConfigurationChanged

Log分析によると、Activityは再構築されず、ライフサイクルのメソッドは呼び出されず、onSaveInstanceStateとonRestoreInstanceStateも呼び出されません.onConfigurationChangedメソッドが呼び出されます.
+++++++++添付情報:configChanges属性の値++++++++++++
この属性を設定することでActivityスナップデバイスの状態を変化させることができます.以下は認識できる内容です.設定方法:以下のフィールドを「|」記号で区切って、例えば「locale|navigation|orientation」などです.
「mcc」国際移動ユーザ識別コードの所属国番号は変更された---simは検出され、mcc mccを更新するのは移動ユーザの所属国番号「mnc」国際移動ユーザ識別コードの移動網番号は変更された---simは検出され、mnc MNCを更新するのは移動網番号であり、最大2桁の数字から構成されている.モバイルユーザの帰属を識別するためのモバイル通信網「locale」アドレスが変更された---ユーザが新しい言語を選択すると「touchscreen」タッチパネルが変更された---通常は発生しない「keyboard」キーボードが変更された---例えばユーザが外部のキーボード「keyboardHidden」キーボードの可用性が変更されたナビゲーションが変更された---通常は「screenLayout」画面の表示が変更された---異なる表示がアクティブになった「fontScale」フォントの割合が変更された---異なるグローバルフォント「uiMode」ユーザーを選択したモードが変更された「orientation」画面方向が変更された「screenSize」画面サイズが変更された「smallestScreenSize」画面の物理的なサイズが変わりました.たとえば、外部の画面に接続すると
参照リンク:http://www.cnblogs.com/-cyb/articles/Android_onConfigurationChanged.html(screenSizeを追加する問題)http://www.cnblogs.com/carlo/p/4311010.html(添付情報:configChanges属性の値)
参考書:Android開発芸術探索.