Activity縦横切り替えの件
10620 ワード
Activityのライフサイクルは、Android開発者一人一人が理解しなければならない知識です.Activityは4つのコンポーネントの1つであり、最も頻繁に使用されるコンポーネントです.縦画面切り替えはAndroid開発者一人一人が直面する問題です.では、縦画面切り替え後のActivityではいったい何が起こっているのでしょうか.
1、ライフサイクルの変化
Activityを作成し、すべてのライフサイクルメソッドを書き換え、これらのメソッドにログを追加します.
このActivityを正常に起動します.
LogでActivityの作成からプレゼンテーションまでのライフサイクルを見ることができます:onCreate()--->onStart()--->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つの方法があります.
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」という値を取得します.
縦横に表示されたログを取得します.
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は再構築されない.次のメソッドも呼び出されます.
コード検証:Activityによるandroidの追加:configChanges="orientation|screenSize"
縦横に切り替えた後:
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開発芸術探索.
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開発芸術探索.