web-dev-qa-db-ja.com

フラグメントアクティビティのcommitAllowingStateLoss()

私のアプリはフラグメントアクティビティを使用します。ポートレートモードのみで、画面を回転させる方法はありません。

もともとcommit()メソッドを使用していましたが、フラグメントアクティビティのためにこれらを無差別にcommitAllowingStateLoss()に変更する予定です

フラグメントを使用する個々のケースを再評価せずに無差別にこれを行わない理由はありますか?

37
CQM

私が正しく理解している場合、あなたは次のことを意味しています:フラグメントを使用する個々のケースを再評価せずに無差別にこれをしない理由はありますか?

答えは「はい」です。フラグメントを使用する個々のケースを慎重に再評価せずにこれを行うべきではありません。

もちろん、設定の変更(画面の回転)による再起動を防ぐことで、主要な問題領域の1つを排除しました。つまり、ユーザーはonSaveInstanceStateを呼び出した後、commitAllowingStateLossの前に画面を回転できます。この場合、UIの一部または一部が失われる可能性があります。これに関する非公式の議論については、これを参照してください post

ただし、commitcommitAllowingStateLossに置き換える前に考慮する必要がある他の状況があります。

  1. 基本的に、onSaveInstanceStateとcommitAllowingStateLossの間のUI更新: Android:IllegalStateException-いつスローされますか?

  2. アクティビティのUIを更新するヘッドレスフラグメントがある場合、それらの更新の一部が失われる可能性があります(これを参照してください article )。

  3. 電話/タブのリソースが不足しているため、Androidはフラグメントを「殺す」可能性があります(これを参照してください answer )。

もちろん、画面の回転が妨げられている場合は、onSaveInstanceStateが呼び出されない場合があります。この場合、更新が失われる機会が増えます。

commitAllowingStateLossを使用することにした場合、リスクを最小限に抑えるためにできることは次のとおりです。親アクティビティが次に再起動されたときにcommit/executePendingTransactionsを実行することを検討してください(これはしたくないが、他の誰かが this と読むかもしれません)。

最後に(ここでも他の誰かがこれを読んだ場合-これはあなたのケースには関係ありません)IllegalStateExceptionを処理する方法は、コミットからcommitAllowStateLossに移動するよりもおそらく安全です。たとえば、コミットに固執し、IllegalStateExceptionを処理できます。または、 bug in Androidにヒットした可能性があり、回避策がある可能性があります。

53
IanB
public abstract int commit ()

このトランザクションのコミットをスケジュールします。コミットはすぐには行われません。メインスレッドでの作業として、次回スレッドの準備ができたときに実行されるようにスケジュールされます。

トランザクションは、状態を保存するアクティビティを含む前に、このメソッドでのみコミットできます。その時点以降にコミットが試行されると、例外がスローされます。これは、アクティビティをその状態から復元する必要がある場合、コミット後の状態が失われる可能性があるためです。コミットを失ってもよい状況については、commitAllowingStateLoss()を参照してください。

public abstract int commitAllowingStateLoss ()

APIレベル11で追加

Commit()と似ていますが、アクティビティの状態が保存された後にコミットを実行できます。これは、アクティビティを後でその状態から復元する必要がある場合にコミットが失われる可能性があるため危険です。したがって、これはUIの状態がユーザーで予期せず変更しても問題ない場合にのみ使用してください。

FragmentActivityの制限

Honeycomb(3.0)より前は、アクティビティの状態は一時停止する前に保存されていました。フラグメントはかなりの量の新しい状態であり、一時停止と停止の間で変更することをしばしば望むほど動的です。これらのクラスは、UI状態が誤って失われないように、フラグメントの状態を保存した後に変更しようとすると例外をスローします。ただし、これは、一時停止する前に状態が保存されるHoneycombより前の制限が強すぎます。これに対処するために、Honeycombより前のプラットフォームで実行している場合、状態の保存と停止中のアクティビティの間でフラグメントを変更しても、例外はスローされません。これは、場合によっては、アクティビティが最後に保存された状態から復元される場合、これはユーザーが最後に見たものより少し前のスナップショットである可能性があることを意味します。

ですから、もしあなたが州の損失に気付いていなければ、あなたの決定は大丈夫だと思います。それがあなたの決断に役立つことを願っています。

5
Diogo Bento
try {
    transaction.commit();
} catch (IllegalStateException e) {
    transaction.commitAllowingStateLoss();
}
3

より良いアイデアは、commitAllowingStateLoss()を無差別に使用するのではなく、OnPostResumeコールバックでcommit()を使用することです。次のブログ投稿では、詳細な説明を提供しています http://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html

@Override
protected void onPostResume() {
    super.onPostResume();
    // Commit your transactions here.
}
2
Varun Bhatia

次のメソッドを次のようにオーバーライドできます

@Override
public void supportFinishAfterTransition() {
    finish();
    super.supportFinishAfterTransition();
}

それは私のために働いた。

0
Juan A. C. Isla