Ich erhalte diesen Fehler selten, wenn ich einen API-Aufruf mache.
java.lang.IllegalStateException: Fragment not attached to Activity
Ich habe versucht, den Code in die isAdded()
Methode einzufügen, um zu überprüfen, ob das Fragment derzeit zu seiner Aktivität hinzugefügt wird, aber ich erhalte diesen Fehler immer noch selten. Ich verstehe nicht, warum ich diesen Fehler immer noch erhalte. Wie kann ich das verhindern?
Es zeigt Fehler in der Zeile
cameraInfo.setId(getResources().getString(R.string.camera_id));
Unten ist der Beispiel-API-Aufruf, den ich mache.
SAPI.getInfo(getActivity(),
new APIResponseListener() {
@Override
public void onResponse(Object response) {
cameraInfo = new SInfo();
if(isAdded()) {
cameraInfo.setId(getResources().getString(R.string.camera_id));
cameraInfo.setName(getResources().getString(R.string.camera_name));
cameraInfo.setColor(getResources().getString(R.string.camera_color));
cameraInfo.setEnabled(true);
}
}
@Override
public void onError(VolleyError error) {
mProgressDialog.setVisibility(View.GONE);
if (error instanceof NoConnectionError) {
String errormsg = getResources().getString(R.string.no_internet_error_msg);
Toast.makeText(getActivity(), errormsg, Toast.LENGTH_LONG).show();
}
}
});
android
android-fragments
android-activity
android-volley
android-lifecycle
Android-Entwickler
quelle
quelle
Antworten:
Dieser Fehler tritt aufgrund der kombinierten Wirkung zweier Faktoren auf:
onResponse()
oderonError()
(die auf dem Hauptthread funktionieren) aufgerufen, ohne zu wissen, ob sich dieActivity
noch im Vordergrund befindet oder nicht. Wenn dasActivity
weg ist (der Benutzer hat woanders navigiert), wirdgetActivity()
null zurückgegeben.Response
wird als anonyme innere Klasse ausgedrückt, die implizit einen starken Bezug zur äußerenActivity
Klasse hat. Dies führt zu einem klassischen Speicherverlust.Um dieses Problem zu lösen, sollten Sie immer Folgendes tun:
und auch
isAdded()
in deronError()
Methode verwenden:quelle
AsyncTask
s aus einem heraus verwendenActivity
, gibt es keine narrensichere Möglichkeit, NPEs zu vermeiden. Es besteht immer die Möglichkeit, dass der Benutzer von der aktuellen Seite weg navigiert,Activity
während einer der Threads etwas im Hintergrund ausführt. Wenn der Thread abgeschlossen ist und /onPostExecute()
oderonResponse()
aufgerufen wird, gibt es keineActivity
. Alles, was Sie tun können, ist, an verschiedenen Stellen in Ihrem Code nachadded
boolesche Flag und ob die aktuelleActivity
Instanz istnull
oder nicht.Der Fragmentlebenszyklus ist sehr komplex und voller Fehler. Versuchen Sie Folgendes hinzuzufügen:
quelle
return mHost != null && mAdded;
- Das ist es, was in der fragment.isAdded () -Methode enthalten ist. Ich dachte, dass mHost eine Aktivität ist, wenn Sie sie verfolgen, aber es scheint, dass sich mHost in FragmentActivity befindet. Also wahrscheinlich hast du recht. Irgendwelche Ergänzungen?Ich habe eine sehr einfache Lösung gefunden. Die Methode isAdded () ist eine der Fragmentmethoden, mit der festgestellt werden kann , ob dieses aktuelle Fragment an seine Aktivität angehängt ist oder nicht.
wir können dies wie überall in Fragmentklassen verwenden wie:
quelle
Ausnahme: java.lang.IllegalStateException: Fragment
DeadlineListFragment {ad2ef970} nicht an Aktivität angehängt
Kategorie: Lebenszyklus
Beschreibung : Bei zeitaufwändigen Vorgängen im Hintergrundthread (z. B. AsyncTask) wurde in der Zwischenzeit ein neues Fragment erstellt, das vor Abschluss des Hintergrundthreads von der Aktivität getrennt wurde. Der Code im UI-Thread (z. B. onPostExecute) ruft ein getrenntes Fragment auf und löst eine solche Ausnahme aus.
Fix Lösung:
Brechen Sie den Hintergrund-Thread ab, wenn Sie das Fragment anhalten oder stoppen
Verwenden Sie isAdded (), um zu überprüfen, ob das Fragment angehängt ist, und um dannResources () aus der Aktivität abzurufen.
quelle
Ich kann zu spät kommen, aber jemandem helfen ..... Die beste Lösung hierfür ist, eine globale Anwendungsklasseninstanz zu erstellen und sie in dem bestimmten Fragment aufzurufen, an das Ihre Aktivität nicht angehängt ist
wie unten
Hier ist die Anwendungsklasse
quelle
Dieser Fehler kann auftreten, wenn Sie ein Fragment instanziieren, das irgendwie nicht instanziiert werden kann:
In meinem Fall habe ich dies getroffen, als ich versuchte zu verwenden:
quelle
Bei der Verwendung von Fragmenten
isAdded()
wird true zurückgegeben, wenn das Fragment derzeit an Activity angehängt ist.Wenn Sie in der Aktivität nachsehen möchten
Hoffe es wird jemandem helfen
quelle
Ich habe den folgenden Ansatz zur Behandlung dieses Problems gewählt. Erstellt eine neue Klasse, die als Wrapper für solche Aktivitätsmethoden fungiert
Wo immer ich auf Ressourcen aus Fragmenten oder Aktivitäten zugreifen muss, anstatt die Methode direkt aufzurufen, verwende ich diese Klasse. Wenn die Aktivität
context
nicht aktiv istnull
, wird der Wert des Assets zurückgegeben, und wenn dercontext
Wert null ist, wird ein Standardwert übergeben (der auch vom Aufrufer der Funktion angegeben wird).Wichtig Dies ist keine Lösung. Dies ist eine effektive Methode, um diesen Absturz ordnungsgemäß zu bewältigen. Sie möchten einige Protokolle hinzufügen, wenn Sie die Aktivitätsinstanz als null erhalten, und versuchen, dies nach Möglichkeit zu beheben.
quelle
Dies geschieht, wenn das Fragment keinen Kontext hat und die Methode getActivity () daher null zurückgibt. Überprüfen Sie, ob Sie den Kontext verwenden, bevor Sie ihn erhalten , oder ob die Aktivität nicht mehr vorhanden ist. Verwenden Sie den Kontext in fragment.onCreate und nach der API-Antwort tritt dieses Problem normalerweise auf
quelle
Manchmal wird diese Ausnahme durch einen Fehler in der Implementierung der Support-Bibliothek verursacht. Vor kurzem musste ich ein Downgrade von 26.1.0 auf 25.4.0 durchführen, um es loszuwerden.
quelle
Dieses Problem tritt immer dann auf, wenn Sie einen Kontext aufrufen, der nicht verfügbar ist, oder null, wenn Sie ihn aufrufen. Dies kann eine Situation sein, in der Sie den Kontext des Hauptaktivitätsthreads in einem Hintergrundthread oder den Kontext des Hintergrundthreads in einem Hauptaktivitätsthread aufrufen.
Zum Beispiel habe ich meine gemeinsame Einstellungszeichenfolge wie folgt aktualisiert.
Und gleich danach finish () aufgerufen. Jetzt läuft das Commit auf dem Hauptthread und stoppt alle anderen Async-Commits, wenn es bis zum Ende kommt. Der Kontext bleibt also lebendig, bis der Schreibvorgang abgeschlossen ist. Daher ist der vorherige Kontext aktiv, wodurch der Fehler auftritt.
Stellen Sie daher sicher, dass Ihr Code erneut überprüft wird, wenn Code mit diesem Kontextproblem vorliegt.
quelle