wake-up-neo.com

java.lang.IllegalStateException: Fragment nicht an Aktivität angehängt

Ich erhalte diesen Fehler selten während eines API-Aufrufs.

Java.lang.IllegalStateException: Fragment  not attached to Activity

Ich habe versucht, den Code in die isAdded()-Methode zu setzen, um zu prüfen, ob das Fragment derzeit zu seiner Aktivität hinzugefügt wird, aber ich bekomme diesen Fehler selten. Ich kann nicht verstehen, warum ich diesen Fehler immer noch bekomme. Wie kann ich das verhindern?

Sein Fehler auf der Leitung

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();
                        }
                    }
                });
113

Dieser Fehler tritt aufgrund des kombinierten Effekts zweier Faktoren auf:

  • Wenn die HTTP-Anforderung abgeschlossen ist, ruft sie entweder onResponse() oder onError() (die im Hauptthread funktionieren) auf, ohne zu wissen, ob sich Activity noch im Vordergrund befindet. Wenn Activity nicht mehr vorhanden ist (der Benutzer ist an anderer Stelle navigiert), gibt getActivity() den Wert null zurück.
  • Die Variable Response wird als anonyme innere Klasse ausgedrückt, die implizit einen starken Verweis auf die äußere Klasse Activity enthält. Dies führt zu einem klassischen Speicherverlust.

Um dieses Problem zu lösen, sollten Sie immer Folgendes tun:

Activity activity = getActivity();
if(activity != null){

    // etc ...

}

verwenden Sie isAdded() auch in der onError()-Methode:

@Override
public void onError(VolleyError error) {

    Activity activity = getActivity(); 
    if(activity != null && isAdded())
        mProgressDialog.setVisibility(View.GONE);
        if (error instanceof NoConnectionError) {
           String errormsg = getResources().getString(R.string.no_internet_error_msg);
           Toast.makeText(activity, errormsg, Toast.LENGTH_LONG).show();
        }
    }
}
169
Y.S.

Der Fragment-Lebenszyklus ist sehr komplex und voller Fehler. 

Activity activity = getActivity(); 
if (isAdded() && activity != null) {
...
}
41

Ich habe eine sehr einfache Lösung gefunden isAdded () - Methode, eine der Fragment-Methoden, um zu identifizieren, ob dieses aktuelle Fragment an seine Aktivität angehängt ist oder nicht.

wir können dies wie überall in der Fragmentklasse verwenden:

if(isAdded())
{

// using this method, we can do whatever we want which will prevent   **Java.lang.IllegalStateException: Fragment not attached to Activity** exception.

}
11
Dharmesh Baldha

Ausnahme: Java.lang.IllegalStateException: Fragment

DeadlineListFragment {ad2ef970} nicht an Aktivität angehängt

Kategorie: Lebenszyklus

Beschreibung : Bei der zeitaufwändigen Operation im Hintergrundthread (z. B. AsyncTask) wurde in der Zwischenzeit ein neues Fragment erstellt und vor dem Abschluss des Hintergrundthreads von der Aktivität getrennt. Der Code im UI-Thread (z. B. onPostExecute) ruft ein getrenntes Fragment auf und löst eine solche Ausnahme aus.

Lösung beheben:

  1. Brechen Sie den Hintergrund-Thread ab, wenn Sie das -Fragment anhalten oder stoppen

  2. Verwenden Sie isAdded (), um zu prüfen, ob das Fragment Angehängt ist, und dann für getResources () aus der Aktivität.

8
Rahil Ali

ich komme möglicherweise zu spät, kann aber jemandem helfen. Die beste Lösung dafür ist, eine globale Anwendungsklasseninstanz zu erstellen und sie in einem bestimmten Fragment aufzurufen, an dem Ihre Aktivität nicht angehängt wird 

wie unten 

icon = MyApplication.getInstance().getString(R.string.weather_thunder);

Hier ist die Anwendungsklasse

public class MyApplication extends Application {

    private static MyApplication mInstance;
    private RequestQueue mRequestQueue;

    @Override
    public void onCreate() {
        super.onCreate();
        mInstance = this;
    }

    public static synchronized MyApplication getInstance() {
        return mInstance;
    }
}
7
md gouse

Dieser Fehler kann auftreten, wenn Sie ein Fragment instanziieren, das irgendwie nicht instanziiert werden kann:

Fragment myFragment = MyFragment.NewInstance();


public classs MyFragment extends Fragment {
  public void onCreate() {
   // Some error here, or anywhere inside the class is preventing it from being instantiated
  }
}

In meinem Fall habe ich dies getroffen, als ich versuchte zu verwenden:

private String loading = getString(R.string.loading);
2
sagits

In Fragment verwenden Sie isAdded() Es wird true zurückgegeben, wenn das Fragment aktuell an Activity angehängt ist.

Wenn Sie die Aktivität überprüfen möchten

 Fragment fragment = new MyFragment();
   if(fragment.getActivity()!=null)
      { // your code here}
      else{
       //do something
       }

Ich hoffe es hilft jemandem

2
Prateek218

Ich habe den folgenden Ansatz gewählt, um dieses Problem zu behandeln. Erstellt eine neue Klasse, die als Wrapper für Aktivitätsmethoden wie diese fungiert

public class ContextWrapper {
    public static String getString(Activity activity, int resourceId, String defaultValue) {
        if (activity != null) {
            return activity.getString(resourceId);
        } else {
            return defaultValue;
        }
    }

    //similar methods like getDrawable(), getResources() etc

}

Wo immer ich auf Ressourcen aus Fragmenten oder Aktivitäten zugreifen muss, anstatt die Methode direkt aufzurufen, verwende ich diese Klasse. Falls die Aktivität context nicht null ist, gibt sie den Wert des Assets zurück, und falls context null ist, übergibt sie einen Standardwert (der auch vom Aufrufer der Funktion angegeben wird).

Wichtig Dies ist keine Lösung, dies ist ein effektiver Weg, um diesen Absturz elegant zu handhaben. Sie möchten einige Protokolle hinzufügen, wenn Sie die Aktivitätsinstanz als null erhalten und versuchen, dies zu beheben, falls dies möglich ist.

1
Ezio

Dieses Problem tritt immer dann auf, wenn Sie einen Kontext aufrufen, der beim Aufruf nicht verfügbar oder null ist. Dies kann eine Situation sein, wenn Sie den Kontext des Hauptaktivitätsthreads in einem Hintergrundthread oder den Kontext des Hintergrundthreads im Hauptaktivitätsthread aufrufen.

Zum Beispiel habe ich meine freigegebene Einstellungszeichenfolge wie folgt aktualisiert.

editor.putString("penname",penNameEditeText.getText().toString());
editor.commit();
finish();

Und rief direkt nach ihm finish () an. Nun ist es so, dass Commit im Haupt-Thread ausgeführt wird und alle anderen Async-Commits angehalten werden, wenn sie kommen, bis der Vorgang abgeschlossen ist. Der Kontext ist also lebendig, bis der Schreibvorgang abgeschlossen ist. Daher ist der vorherige Kontext live, wodurch der Fehler auftritt.

Stellen Sie daher sicher, dass Ihr Code erneut überprüft wird, wenn Code mit diesem Kontextproblem vorliegt. 

0

Manchmal wird diese Ausnahme durch einen Fehler in der Implementierung der Unterstützungsbibliothek verursacht. Vor kurzem musste ich von 26.1.0 auf 25.4.0 herabstufen, um es loszuwerden.

0
Bord81

dies geschieht, wenn das Fragment keinen Kontext hat. Die Methode getActivity () gibt also null zurück. Prüfen Sie, ob Sie den Kontext verwenden, bevor Sie ihn abrufen, oder ob die Aktivität nicht mehr vorhanden ist. Verwenden Sie den Kontext in fragment.onCreate und nach einer API-Antwort normalerweise dieses Problem

0
dexian fan