2012-04-12 12 views
30

画面の回転を処理する最良の方法が何であるかを理解しています。私はここで何百もの質問/回答を読みましたが、私は本当に混乱しています。データを失うことなく画面を回転させる - Android

活動がそのように私は別の役に立たない初期化せずに活動を再描画のためにすべてを保つことができ、再作成される前に、どのように私はMyClassのデータを保存することができますか?

パーセル可能なクリーナーよりも優れた方法がありますか?

ランドスケープモードでレイアウトを変更したいので、回転を処理する必要があります。

public class MtgoLifecounterActivity extends Activity { 

    MyClass myClass; 

    // Called when the activity is first created 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     If (?? first run...myClass == null ?) { 
      myClass = new MyClass(); 
     } else { 
      // do other stuff but I need myClass istance with all values. 
     } 
     // I want that this is called only first time. 
     // then in case of rotation of screen, i want to restore the other instance of myClass which 
     // is full of data. 
    } 
+0

参照、 'onConfigurationChanged'のものを使用します。http://stackoverflow.com/questions/456211/activity-restart-on-rotation-android – Nanne

答えて

21

はオーバーライドメソッドonSaveInstanceState()onRestoreInstanceState()を使用することができます。 またはちょうどあなたのマニフェストXMLでandroid:configChanges="keyboardHidden|orientation"

ノートをこの行を追加し、画面の回転にonCreate()を呼び出しを停止するには:カスタムクラスは以下のParcelable例を実装しなければなりません。

@Override 
    public void onSaveInstanceState(Bundle outState) { 
     super.onSaveInstanceState(outState); 
     outState.putParcelable("obj", myClass); 
    } 

@Override 
protected void onRestoreInstanceState(Bundle savedInstanceState) { 
// TODO Auto-generated method stub 
super.onRestoreInstanceState(savedInstanceState); 
myClass=savedInstanceState.getParcelable("obj")); 
} 

public class MyParcelable implements Parcelable { 
    private int mData; 

public int describeContents() { 
    return 0; 
} 

/** save object in parcel */ 
public void writeToParcel(Parcel out, int flags) { 
    out.writeInt(mData); 
} 

public static final Parcelable.Creator<MyParcelable> CREATOR 
     = new Parcelable.Creator<MyParcelable>() { 
    public MyParcelable createFromParcel(Parcel in) { 
     return new MyParcelable(in); 
    } 

    public MyParcelable[] newArray(int size) { 
     return new MyParcelable[size]; 
    } 
}; 

/** recreate object from parcel */ 
private MyParcelable(Parcel in) { 
    mData = in.readInt(); 
} 


} 
+0

しかし、私はonSaveInstanceStateとonRestoreInstanceStateを実行する必要がありますか? parcelableを実装しますか? –

+0

はい、パーセルブルを実装する必要があります。 –

+0

pffffは存在しません。私はクラスのInstantAutoCompleteを拡張する必要があります。AutoTextViewから拡張したものです。EditTextはFilter.FilterListenerを実装しています....すべての値を取得するには1日失います.... – delive

1

あなたがあなたの活動を再開するための必要性を持っていない場合だけconfigChangesはこれにAndroidManifest.xmlをして、あなたの活動に属性を設定:

android:configChanges="keyboard|keyboardHidden|orientation" 

これはあなたのOSを教えてくれますローテーションを処理することになり、あなたのアクティビティは再開しません。この方法を使用すると、あらゆる種類の状態を保存する必要がなくなります。

+0

これはそうではありません、グーグルのdevの者がこれに反対をお勧めしていますこれは、オリエンテーションの変更だけがアクティビティが廃棄され再作成される唯一の理由であると仮定しているため、実際にこのようなことが起こる他の多くの理由があります。 – BenjaminPaul

2

これには2つの(良い)方法があります。クラスにParcelableを実装してonSaveInstanceState()のバンドルに入れるか、複雑な場合(AsyncTaskなど)onRetainNonConfigurationInstance()に返します。

また、設定変更に反応することを止める怠惰な方法もあります。

+0

これは推奨されていないようです!はい、それは非常に複雑なオブジェクトです - onRetainNonConfigurationInstance() –

+0

うわー、彼らは 'onRetainNonConfigurationInstance()'を非難しましたが、私が知る限り、代替を提供しませんでした。 – dmon

+0

@dmonは、代わりにUIなしでフラグメントを使用する可能性があります。https://developer.android.com/reference/android/app/Fragment.html#setRetainInstance(boolean) –

27

マニフェストのアクティビティタグでは、あなたは、Android 2.3(APIレベル13)を使用している場合

<activity 
     android:name="com.example.ListActivity" 
     android:label="@string/app_name" 
     android:configChanges="keyboardHidden|orientation"> 

に言及し、それが動作する必要があります

<activity 
     android:name="com.example.Activity" 
     android:label="@string/app_name" 
     android:configChanges="keyboardHidden|orientation|screenSize"> 
使用

の上にする必要があります。

それだけ活動タグと連携し、アプリケーションでタグ

+2

問題はscreenSize属性にありました。ありがとうございますPrashant – bebosh

+1

いつもようこそ:)... @bebosh – Cool7

11

が、これはすでに解決しているかもしれないが、それに引っかかって新しいメンバーのための小さな更新のために、ちょうどGoogle Developer Siteで見ていません、APIレベル13から、あなただけのマニフェストにこのコードを追加する必要があります。

<activity android:name=".SplashScreensActivity" 
      android:configChanges="orientation|keyboardHidden|screenSize" 
      android:label="@string/app_name"> 

これらの構成のいずれかが変化し、SplashScreensActivityは再起動しません。代わりに、SplashScreensActivityはonConfigurationChanged()の呼び出しを受け取ります。このメソッドには、新しいデバイス構成を指定するConfigurationオブジェクトが渡されます。コンフィグレーションのフィールドを読み込むことで、新しいコンフィグレーションを決定し、インタフェースで使用されるリソースを更新して適切な変更を加えることができます。このメソッドが呼び出された時点で、アクティビティのResourcesオブジェクトが更新され、新しいコンフィグレーションに基づいてリソースが返されるため、システムのアクティビティを再起動することなく簡単にUIの要素をリセットできます。

1

ここで問題となるのは、アプリケーションの「状態」が失われていることです。 OOPでは、状態は何ですか?変数!まったく!したがって、あなたが変数のデータを失っているとき。

ここで、あなたの状態を失っている変数を見つけてください。

enter image description here

は、あなたのデバイスを回転すると、あなたの現在の活動は完全に破壊されます、つまりはonSaveInstanceState()onPause() onStop() onDestroy()を通過し、新しい活動がonCreate() onStart()onRestoreInstanceStateを通過した、完全に作成されます。

太字の2つのメソッドonSaveInstanceState()は、破棄される現在のアクティビティのインスタンスを保存します。 onRestoreInstanceStateこのメソッドは、以前のアクティビティの保存された状態を復元します。あなたはアプリの以前の状態を失うことはありませんこのように。

これらの方法は次のとおりです。

@Override 
    public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) { 
     super.onSaveInstanceState(outState, outPersistentState); 

     outState.putString("theWord", theWord); // Saving the Variable theWord 
     outState.putStringArrayList("fiveDefns", fiveDefns); // Saving the ArrayList fiveDefns 
    } 

    @Override 
    public void onRestoreInstanceState(Bundle savedInstanceState, PersistableBundle persistentState) { 
     super.onRestoreInstanceState(savedInstanceState, persistentState); 

     theWord = savedInstanceState.getString("theWord"); // Restoring theWord 
     fiveDefns = savedInstanceState.getStringArrayList("fiveDefns"); //Restoring fiveDefns 
    } 
関連する問題