webentwicklung-frage-antwort-db.com.de

commitAllowingStateLoss () in Fragmentaktivitäten

meine App verwendet Fragment-Aktivitäten. Sie befindet sich nur im Hochformat und es gibt keine Möglichkeit, den Bildschirm zu drehen.

Ursprünglich verwendete ich die commit()-Methode, aber jetzt plane ich, diese für die Fragment-Aktivitäten wahllos in commitAllowingStateLoss() zu ändern

Gibt es einen Grund, dies nicht willkürlich zu tun, ohne jeden einzelnen Fall, in dem ich ein Fragment verwende, neu zu bewerten?

34
CQM

Wenn ich das richtig verstehe, meinen Sie: Gibt es einen Grund, KEINE Entscheidung zu treffen, ohne jeden einzelnen Fall, in dem ich ein Fragment verwende, neu zu bewerten?

Die Antwort lautet Ja - Sie sollten dies nicht tun, ohne sorgfältig jeden einzelnen Fall, in dem Sie ein Fragment verwenden, neu zu bewerten. 

Durch das Verhindern von Neustarts aufgrund von Konfigurationsänderungen (Bildschirmdrehungen) haben Sie natürlich einen der Hauptproblembereiche beseitigt: Das heißt, der Benutzer könnte den Bildschirm NACH einem Aufruf von onSaveInstanceState drehen, jedoch VOR der commitAllowingStateLoss. In diesem Fall kann ein Fragment oder ein Teil der Benutzeroberfläche verloren gehen. Eine informelle Diskussion dazu finden Sie in diesem post .

Es gibt jedoch andere Situationen, die Sie berücksichtigen sollten, bevor Sie commit durch commitAllowingStateLoss ersetzen.

  1. Grundsätzlich alle UI-Updates zwischen onSaveInstanceState und commitAllowingStateLoss: Android: IllegalStateException - Wann wird es ausgelöst?

  2. Wenn Sie über Headless-Fragmente verfügen, die die Benutzeroberfläche Ihrer Aktivität aktualisieren, gehen möglicherweise einige ihrer Updates verloren (siehe article ).

  3. Android kann ein Fragment "töten", da die Ressourcen auf dem Telefon/Tab zu knapp werden (siehe answer ).

Wenn Bildschirmdrehungen verhindert werden, kann onSaveInstanceState natürlich nicht aufgerufen werden. In diesem Fall wird das Zeitfenster für den Verlust eines Updates vergrößert.

Wenn Sie sich für commitAllowingStateLoss entscheiden, können Sie Maßnahmen ergreifen, um die damit verbundenen Risiken zu minimieren: z. Erwägen Sie, eine commitexecutePendingTransactions auszuführen, wenn die übergeordnete Aktivität das nächste Mal neu gestartet wird (ich weiß, dass Sie dies nicht tun möchten, aber jemand anderes könnte _/this lesen).

Schließlich (wieder, falls jemand anderes dies liest - dies ist in Ihrem Fall nicht relevant), gibt es wahrscheinlich sicherere Wege, eine IllegalStateException zu handhaben, als vom Festschreiben zu commitAllowStateLoss zu wechseln. Zum Beispiel könnten Sie einfach bei commit bleiben und die IllegalStateException behandeln. Alternativ haben Sie möglicherweise einen bug in Android getroffen, und es gibt möglicherweise eine Problemumgehung.

48
IanB
public abstract int commit ()

Plant ein Commit dieser Transaktion. Das Commit geschieht nicht sofort; Es wird als Arbeit für den Haupt-Thread geplant, der beim nächsten Bereitstellen des Threads ausgeführt werden soll.

Eine Transaktion kann nur mit dieser Methode festgeschrieben werden, bevor die enthaltene Aktivität ihren Status speichert. Wenn das Festschreiben nach diesem Punkt versucht wird, wird eine Ausnahme ausgelöst. Dies liegt daran, dass der Zustand nach dem Festschreiben verloren gehen kann, wenn die Aktivität aus ihrem Zustand wiederhergestellt werden muss. Siehe commitAllowingStateLoss () für Situationen, in denen der Commit verloren gehen kann.

public abstract int commitAllowingStateLoss ()

In API Level 11 hinzugefügt

Wie commit (), ermöglicht jedoch die Ausführung des Commits, nachdem der Status einer Aktivität gespeichert wurde. Dies ist gefährlich, da das Festschreiben verloren gehen kann, wenn die Aktivität später aus ihrem Status wiederhergestellt werden muss. Daher sollte dies nur für Fälle verwendet werden, in denen der UI-Status für den Benutzer unerwartet geändert werden kann.

FragmentActivity Einschränkungen

Vor Honeycomb (3.0) wurde der Status einer Aktivität vor dem Anhalten gespeichert. Fragmente sind eine bedeutende Menge neuer Zustände und so dynamisch, dass man oft wünscht, dass sie zwischen Anhalten und Anhalten wechseln. Diese Klassen lösen eine Ausnahme aus, wenn Sie versuchen, den Fragmentstatus nach dem Speichern zu ändern, um einen versehentlichen Verlust des UI-Status zu vermeiden. Dies ist jedoch vor Honeycomb zu restriktiv, wo der Zustand vor der Pause gespeichert wird. Um dies zu beheben, wird beim Ausführen auf Plattformen vor Honeycomb keine Ausnahme ausgelöst, wenn Sie die Fragmente zwischen dem Speichern des Status und der angehaltenen Aktivität ändern. Dies bedeutet, dass in einigen Fällen, wenn die Aktivität aus dem zuletzt gespeicherten Status wiederhergestellt wird, dies möglicherweise eine Momentaufnahme ist, die sich etwas vor dem, was der Benutzer zuletzt gesehen hat, befindet.

Wenn Sie also nicht mit dem Staatsverlust konfrontiert sind, denke ich, dass Ihre Entscheidung in Ordnung ist. Ich hoffe, es hilft Ihnen bei Ihrer Entscheidung.

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

Eine bessere Idee wäre, commit () in OnPostResume-Callbacks zu verwenden, statt willkürlich commitAllowingStateLoss () zu verwenden. Der folgende Blogpost bietet eine ausführliche Erklärung 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

Sie können die nächste Methode wie folgt überschreiben

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

es hat für mich funktioniert.

0
Juan A. C. Isla