私のAndroidアプリケーションでは、デバイスを回転させる(キーボードを引き出す)とActivity再起動します(onCreateと呼ばれています。さて、これはおそらくそれが想定されている方法ですが、私は初期設定の多くをやっていますonCreateメソッドなので、次のどちらかが必要です。
onCreate再度呼び出されることはなく、レイアウトが調整されるだけです。onCreateと呼ばれていません。
アプリケーションクラスの使い方
初期化で何をしているかに応じて、拡張する新しいクラスを作成することを検討できます。Application初期化コードをオーバーライドするonCreateそのクラス内のメソッド。
public class MyApplicationClass extends Application {
  @Override
  public void onCreate() {
    super.onCreate();
    // TODO Put your application initialization code here.
  }
}
のonCreateアプリケーションクラスでは、アプリケーション全体が作成されたときにのみ呼び出されるため、Activityが向きを変えて再起動したり、キーボードの表示設定が変更されたりすることはありません。
このクラスのインスタンスをシングルトンとして公開し、初期化しているアプリケーション変数をゲッターとセッターを使用して公開することをお勧めします。
注:登録して使用するには、マニフェストに新しいApplicationクラスの名前を指定する必要があります。
<application
    android:name="com.you.yourapp.MyApplicationClass"
構成変更への対応 [更新:これはAPI 13以降廃止予定です。推奨代替案を参照してください]
さらに別の方法として、向きやキーボードの表示設定の変更など、再起動の原因となるイベントをアプリケーションにリッスンさせ、それらをActivity内で処理することもできます。
を追加することから始めますandroid:configChangesアクティビティのマニフェストノードへのノード
android:configChanges="keyboardHidden|orientation"
またはのためにAndroid 3.2(APIレベル13)以降:
android:configChanges="keyboardHidden|orientation|screenSize"
次に、アクティビティ内でonConfigurationChangedメソッドと呼び出しsetContentViewGUIレイアウトを新しい向きで強制的に再作成します。
@Override
public void onConfigurationChanged(Configuration newConfig) {
  super.onConfigurationChanged(newConfig);
  setContentView(R.layout.myLayout);
}
                    
                                            android:configChanges)回避し、最後の手段としてのみ使用する必要があります。設定変更による再起動を適切に処理する方法については、ランタイム変更の処理を参照してください。代わりに、ローテーションイベント間でデータを永続化するには、onSaveInstanceState Bundle;または@ Jon-Oとして推薦、onRetainNonConfigurationInstance。 - JeffroonRetainNonConfigurationChangesよりフォールトトレラントで簡単です。 - Bananeweizen
Android 3.2以降用に更新します。
あぶない:Android 3.2(APIレベル13)以降「画面サイズ」も変わりますデバイスが縦向きと横向きの間で切り替わるとき。したがって、(minSdkVersion属性およびtargetSdkVersion属性で宣言されているように)APIレベル13以上で開発する際の向きの変更によるランタイムの再起動を防ぐには、次のものを含める必要があります。
"screenSize"に加えて値"orientation"値。つまり、宣言する必要がありますandroid:configChanges="orientation|screenSize"。ただし、アプリケーションがAPIレベル12以下をターゲットにしている場合、アクティビティは常にこの設定変更自体を処理します(Android 3.2以降のデバイスで実行している場合でも、この設定変更はアクティビティを再開しません)。
FragmentsそしてsetRetainInstance代わりに。 - Simon ForsbergscreenSizeアンドロイド3.2以降では、それが私の問題を解決しました、ありがとうございます! - fantouch
停止しようとする代わりにonCreate()完全に解雇されることから、多分Bundle
savedInstanceStatenullかどうかを確認するためにイベントに渡されます。
たとえば、次のような場合に実行する必要があるロジックがあるとします。Activityすべての向きの変更ではなく、私は本当にその論理を実行します。onCreate()の場合のみsavedInstanceState無効です。
それ以外の場合は、レイアウトを向きに合わせて正しく再描画する必要があります。
public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_game_list);
        if(savedInstanceState == null){
            setupCloudMessaging();
        }
}
これが最終的な答えであるかどうかわからないが、それは私のために働く。
Intent serverintent = new Intent(MainActivity.this, MessageListener.class);そしてstartService(serverintent);を作成するserverSocket = new ServerSocket(0xcff2);そしてSocket client = serverSocket.accept();とともにBufferedReader(new InputStreamReader(client.getInputStream()));そして私のアンドロイドを回転させ、クライアント/サーバー接続をアクティブに保ちながらGUIを回転させることができます。マニュアルによると、savedInstanceStateは最後のアクティビティがシャットダウンされたときに初期化されます。 - Fred F
私がしたこと...
マニフェストのactivityセクションに、次のように追加されています。
android:configChanges="keyboardHidden|orientation"
アクティビティのコードに、次のものを実装した。
//used in onCreate() and onConfigurationChanged() to set up the UI elements
public void InitializeUI()
{
    //get views from ID's
    this.textViewHeaderMainMessage = (TextView) this.findViewById(R.id.TextViewHeaderMainMessage);
    //etc... hook up click listeners, whatever you need from the Views
}
//Called when the activity is first created.
@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    InitializeUI();
}
//this is called when the screen rotates.
// (onCreate is no longer called when screen rotates due to manifest, see: android:configChanges)
@Override
public void onConfigurationChanged(Configuration newConfig)
{
    super.onConfigurationChanged(newConfig);
    setContentView(R.layout.main);
    InitializeUI();
}
                    
                                            FragmentsそしてsetRetainInstance代わりに。 - Simon Forsberg
あなたが説明するのは、デフォルトの動作です。以下を追加して、これらのイベントを自分で検出して処理する必要があります。
android:configChanges
あなたのマニフェスト、そしてあなたが処理したい変更に。オリエンテーションのために、あなたは使うでしょう:
android:configChanges="orientation"
キーボードを開閉するには、次のようにします。
android:configChanges="keyboardHidden"
両方を処理したい場合は、次のようにpipeコマンドでそれらを分離するだけです。
android:configChanges="keyboardHidden|orientation"
これはあなたが呼び出すどんなActivityにおいてもonConfigurationChangedメソッドを引き起こすでしょう。メソッドをオーバーライドすると、新しい値を渡すことができます。
お役に立てれば。
android:configChanges="orientation"少なくともAndroid 2.1では、エミュレータのバグのみを引き起こすようです。 - Liudvikas BukysFragmentsそしてsetRetainInstance代わりに。 - Simon Forsberg
私はちょうどこの伝承を発見しました:
方向を変えても活動を維持し、それを介して処理するためonConfigurationChanged、ドキュメントそして上記のコードサンプルこれをマニフェストファイルで提案します。
android:configChanges="keyboardHidden|orientation"
これは常に機能するという追加の利点があります。
ボーナスロアは、省略することですkeyboardHidden論理的に思えるかもしれませんが、エミュレータでエラーが発生します(少なくともAndroid 2.1の場合)。orientationエミュレータが両方を呼び出すようにしますOnCreateそしてonConfigurationChanged時々、そしてただOnCreate別の時に。
私はデバイス上の失敗を見たことがありませんが、私はエミュレータが他の人に失敗することについて聞いたことがあります。そのため、記録する価値があります。
FragmentsそしてsetRetainInstance代わりに。 - Simon Forsberg
また、向きを変えてもデータを保持するAndroidプラットフォームの方法を使用することも検討できます。onRetainNonConfigurationInstance()そしてgetLastNonConfigurationInstance()。
これにより、サーバーのフェッチから取得した情報やその他の方法で計算されたものなど、構成の変更をまたがってデータを保持できます。onCreateまたはそれ以来、Androidもあなたの再レイアウトを許可しながらActivity現在使用中の向きにxmlファイルを使用する。
これらのメソッドは現在推奨されていないので、これらのメソッドは推奨されなくなりました(上記の解決策の大部分が示すように向きを処理するよりももっと柔軟です)。Fragmentsそして代わりに使うsetRetainInstance(true)それぞれのFragment保持したい
この方法は便利ですが、フラグメントを使用する場合は不完全です。
通常、フラグメントは設定変更時に再作成されます。これが起こらないようにするには、
setRetainInstance(true);フラグメントのコンストラクタ内
これにより、構成変更中にフラグメントが保持されます。
http://developer.android.com/reference/android/app/Fragment.html#setRetainInstance(boolean)
setRetainInstance()メソッド@ Abdoが述べた。 - brianmearns
単に追加しました
     android:configChanges="keyboard|keyboardHidden|orientation"
マニフェストファイルに追加しなかったどれかonConfigurationChanged私の活動の方法。
<application ...android:configChanges="keyboard|keyboardHidden|orientation">そしてそれは働いています。 build.gradleでの私の設定:minSdkVersion 15, compileSdkVersion 23, buildToolsVersion "23.0.2" - Junior M
onConfigurationChanged is called when the screen rotates. (onCreate is no longer called when screen rotates due to manifest, see: android:configChanges)
マニフェストのどの部分がそれを伝えますonCreate()「?
また、
グーグルの文書は使用を避けるように言うandroid:configChanges(最後の手段としてを除く)....しかし、その後、彼らはすべてを示唆している代替方法行うつかいますandroid:configChanges。
エミュレータが常に呼び出すのは私の経験でしたonCreate()回転時に
しかし、私が同じコードを実行している1〜2台のデバイスは違います。
(なぜ違いがあるのかわからない)
この行をマニフェストに追加してください -
android:configChanges="orientation|keyboard|keyboardHidden|screenSize|screenLayout|uiMode"
そして、このスニペットのアクティビティは次のとおりです。 -
@Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
    }
                    
                                            
のonCreateメソッドを変更してもメソッドは呼び出されますorientationアンドロイドだから、この方法にすべての重い機能を移動することはあなたを助けることにはならないでしょう
以下のコードをあなたの中に入れてください<activity>日中Manifest.xml:
android:configChanges="screenLayout|screenSize|orientation"
                    
                                    
Androidマニフェストに加えられる変更は次のとおりです。
android:configChanges="keyboardHidden|orientation" 
活動の中で行われる追加事項は以下のとおりです。
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    // Checks the orientation of the screen
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
        Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
    }
}
                    
                                    
それはとても簡単です。
<activity
    android:name=".Test"
    android:configChanges="orientation|screenSize"
    android:screenOrientation="landscape" >
</activity>
これは私のために働く:
注意:オリエンテーションはあなたの必要条件によります
これを行うにはいくつかの方法があります。
アクティビティの状態は次の場所に保存できます。onSaveInstanceState。
@Override
public void onSaveInstanceState(Bundle outState) {
    /*Save your data to be restored here
    Example : outState.putLong("time_state", time); , time is a long variable*/
    super.onSaveInstanceState(outState);
}
それからbundle状態を復元します。
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if(savedInstanceState!= null){
       /*When rotation occurs
        Example : time = savedInstanceState.getLong("time_state", 0); */
    } else {
      //When onCreate is called for the first time
    }
}
もう1つの選択肢は、自分で向きの変更を処理することです。しかし、これは良い習慣とは考えられていません。
これをマニフェストファイルに追加してください。
android:configChanges="keyboardHidden|orientation"
Android 3.2以降の場合
android:configChanges="keyboardHidden|orientation|screenSize"
@Override
public void onConfigurationChanged(Configuration config) {
    super.onConfigurationChanged(config);
if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
        //Handle rotation from landscape to portarit mode here
    } else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE){
        //Handle rotation from portrait to landscape mode here
    }
}
回転を避けるために、あなたの活動を縦モードまたは横モードに制限することもできます。
これをマニフェストファイルのactivityタグに追加します。
        android:screenOrientation="portrait"
あるいはあなたの活動の中でプログラム的にこれを実装する:
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
                    
                                    
私はこれを行うことがわかった方法を使用していますonRestoreInstanceStateそしてそのonSaveInstanceStateに何かを保存するイベントBundle(変数を保存する必要がなくても、そこに何かを入れてください。Bundle空ではありません)。それから、onCreate方法は、Bundle空の場合は初期化し、そうでない場合は初期化します。
「Androidのやり方」ではありませんが、自分自身で向きの変更を処理し、変更された向きを考慮に入れるためにビュー内でウィジェットの位置を変更するだけで、非常に良い結果が得られました。ビューを保存して復元する必要がないため、これは他の方法よりも高速です。また、再配置されたウィジェットはまったく同じウィジェットで、移動やサイズ変更を行っただけなので、よりシームレスなエクスペリエンスをユーザーに提供します。このようにして、モデルの状態だけでなくビューの状態も保存できます。
RelativeLayout時々自分自身の向きを変えなければならないビューには、時には良い選択になる可能性があります。それぞれの子ウィジェットに対して、それぞれに異なる相対配置規則を使用して、一連の縦型レイアウトパラメータと一連の美しいレイアウトパラメータを指定するだけです。その後、あなたの中にonConfigurationChanged()方法では、適切なものをsetLayoutParams()子供たち一人ひとりに電話してください。任意の子コントロール自体がする必要がある場合内的に向きを変えると、その子のメソッドを呼び出して向きを変えるだけです。その子も同様にのいずれかのメソッドを呼び出しますその内部の向きの変更などを必要とする子コントロール。
注意:将来、誰かが私と同じ問題に直面した場合、私はこの答えを投稿します。私にとっては、次の行では不十分でした。
android:configChanges="orientation"
画面を回転させたときに、メソッド `onConfigurationChanged(Configuration newConfig)が呼び出されませんでした。
溶液:問題が方向性に関係していたとしても、私はまた "screenSize"を追加しなければなりませんでした。 AndroidManifest.xmlファイルで、これを追加します。
android:configChanges="keyboardHidden|orientation|screenSize"
それからメソッドを実装するonConfigurationChanged(Configuration newConfig)
onSavedInstanceStateメソッドを使用して、すべての値をそのパラメータに格納する必要があります。
@Override
    public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
        super.onSaveInstanceState(outState, outPersistentState);
        outPersistentState.putBoolean("key",value);
    }
そして使う
@Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        savedInstanceState.getBoolean("key");
    } 
オブジェクトを表示して値を取得して設定する 画面の回転を処理します
画面が回転するたびに、開かれたアクティビティは終了し、onCreate()が再度呼び出されます。
1。画面を回転させたときにアクティビティの状態を保存することで、アクティビティのonCreate()が再度呼び出されたときに古いものをすべて復元できます。 参照してくださいこのリンク
2。アクティビティの再開を防ぎたい場合は、manifest.xmlファイルに次の行を追加してください。
  <activity android:name=".Youractivity"
  android:configChanges="orientation|screenSize"/>
                    
                                    
の活動セクションでmanifest、追加:
android:configChanges="keyboardHidden|orientation"
                    
                                    
この行をマニフェストに追加します。
android:configChanges="orientation|screenSize"
人々はあなたが使うべきだと言っています
android:configChanges="keyboardHidden|orientation"
しかし、Androidでローテーションを処理するための最善かつ最も専門的な方法は、Loaderクラスを使用することです。それは有名なクラスではありません(私はその理由がわかりません)が、AsyncTaskよりもずっと優れています。詳細については、UdacityのAndroidコースにあるAndroidチュートリアルを読むことができます。
もちろん、別の方法として、onSaveInstanceStateを使用して値またはビューを格納し、onRestoreInstanceStateを使用してそれらを読み取ることもできます。それは本当にあなた次第です。
試行錯誤の末、私はほとんどの状況で私のニーズに合った解決策を見つけました。これがコードです:
マニフェスト設定:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.pepperonas.myapplication">
    <application
        android:name=".App"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:configChanges="orientation|keyboardHidden|screenSize">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>
</manifest>
MainActivity:
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private static final String TAG = "MainActivity";
    private Fragment mFragment;
    private int mSelected = -1;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate  " + "");
        // null check not realy needed - but just in case...
        if (savedInstanceState == null) {
            initUi();
            // get an instance of FragmentTransaction from your Activity
            FragmentManager fragmentManager = getSupportFragmentManager();
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
            /*IMPORTANT: Do the INITIAL(!) transaction only once!
            * If we call this everytime the layout changes orientation,
            * we will end with a messy, half-working UI.
            * */
            mFragment = FragmentOne.newInstance(mSelected = 0);
            fragmentTransaction.add(R.id.frame, mFragment);
            fragmentTransaction.commit();
        }
    }
    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        Log.d(TAG, "onConfigurationChanged  " +
                   (newConfig.orientation
                    == Configuration.ORIENTATION_LANDSCAPE
                    ? "landscape" : "portrait"));
        initUi();
        Log.i(TAG, "onConfigurationChanged - last selected: " + mSelected);
        makeFragmentTransaction(mSelected);
    }
    /**
     * Called from {@link #onCreate} and {@link #onConfigurationChanged}
     */
    private void initUi() {
        setContentView(R.layout.activity_main);
        Log.d(TAG, "onCreate  instanceState == null / reinitializing..." + "");
        Button btnFragmentOne = (Button) findViewById(R.id.btn_fragment_one);
        Button btnFragmentTwo = (Button) findViewById(R.id.btn_fragment_two);
        btnFragmentOne.setOnClickListener(this);
        btnFragmentTwo.setOnClickListener(this);
    }
    /**
     * Not invoked (just for testing)...
     */
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Log.d(TAG, "onSaveInstanceState  " + "YOU WON'T SEE ME!!!");
    }
    /**
     * Not invoked (just for testing)...
     */
    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        Log.d(TAG, "onSaveInstanceState  " + "YOU WON'T SEE ME, AS WELL!!!");
    }
    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, "onResume  " + "");
    }
    @Override
    protected void onPause() {
        super.onPause();
        Log.d(TAG, "onPause  " + "");
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy  " + "");
    }
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_fragment_one:
                Log.d(TAG, "onClick btn_fragment_one " + "");
                makeFragmentTransaction(0);
                break;
            case R.id.btn_fragment_two:
                Log.d(TAG, "onClick btn_fragment_two " + "");
                makeFragmentTransaction(1);
                break;
            default:
                Log.d(TAG, "onClick  null - wtf?!" + "");
        }
    }
    /**
     * We replace the current Fragment with the selected one.
     * Note: It's called from {@link #onConfigurationChanged} as well.
     */
    private void makeFragmentTransaction(int selection) {
        switch (selection) {
            case 0:
                mFragment = FragmentOne.newInstance(mSelected = 0);
                break;
            case 1:
                mFragment = FragmentTwo.newInstance(mSelected = 1);
                break;
        }
        // Create new transaction
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        // Replace whatever is in the fragment_container view with this fragment,
        // and add the transaction to the back stack
        transaction.replace(R.id.frame, mFragment);
        /*This would add the Fragment to the backstack...
        * But right now we comment it out.*/
        //        transaction.addToBackStack(null);
        // Commit the transaction
        transaction.commit();
    }
}
そしてフラグメントのサンプル:
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
 * @author Martin Pfeffer (pepperonas)
 */
public class FragmentOne extends Fragment {
    private static final String TAG = "FragmentOne";
    public static Fragment newInstance(int i) {
        Fragment fragment = new FragmentOne();
        Bundle args = new Bundle();
        args.putInt("the_id", i);
        fragment.setArguments(args);
        return fragment;
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Log.d(TAG, "onCreateView  " + "");
        return inflater.inflate(R.layout.fragment_one, container, false);
    }
}
で見つけることができますギトブ。
つかいますorientation異なる方向で異なるタスクを実行するためのリスナー。
@Override
public void onConfigurationChanged(Configuration myConfig) 
{
    super.onConfigurationChanged(myConfig);
    int orient = getResources().getConfiguration().orientation; 
    switch(orient) 
    {
       case Configuration.ORIENTATION_LANDSCAPE:
          setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
                    break;
       case Configuration.ORIENTATION_PORTRAIT:
          setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
                    break;
       default:
          setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
    }
}
                    
                                    
この下のコードをあなたのActivityにAndroid Manifest。
android:configChanges="orientation"
向きを変えても、これでアクティビティが再開されることはありません。
で画面の向き(横または縦)を修正します。AndroidManifest.xml
android:screenOrientation="portrait"またはandroid:screenOrientation="landscape"
このためあなたのonResume()メソッドは呼び出されません。
あなたはこのコードを使って画面の現在の向きに固定することができます...
int currentOrientation =context.getResources().getConfiguration().orientation;
        if (currentOrientation == Configuration.ORIENTATION_PORTRAIT) {
            ((Activity) context).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        } else {
            ((Activity) context). setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        }
                    
                                    
あなたの活動の中でViewModelオブジェクトを使うことができます。
ViewModelオブジェクトは、構成の変更中に自動的に保持されるため、保持しているデータはすぐに次のアクティビティまたはフラグメントインスタンスで利用できるようになります。 続きを読む:
https://developer.android.com/topic/libraries/architecture/viewmodel