Ich benutze OkHttp und habe mich gerade diesem Problem gestellt.
Für den ersten Teil war @thucnguyen auf dem richtigen Weg .
Dies geschah, wenn Sie getActivity () in einem anderen Thread aufrufen, der beendet wurde, nachdem das Fragment entfernt wurde. Der typische Fall ist der Aufruf von getActivity () (z. B. für einen Toast), wenn eine HTTP-Anforderung abgeschlossen ist (z. B. in onResponse).
Einige HTTP-Aufrufe wurden auch nach Abschluss der Aktivität ausgeführt (da es eine Weile dauern kann, bis eine HTTP-Anforderung abgeschlossen ist). Ich habe dann durch das HttpCallback
versucht, einige Fragmentfelder zu aktualisieren und habe null
beim Versuch eine Ausnahme bekommen getActivity()
.
http.newCall(request).enqueue(new Callback(...
onResponse(Call call, Response response) {
...
getActivity().runOnUiThread(...) // <-- getActivity() was null when it had been destroyed already
IMO besteht die Lösung darin , Rückrufe zu verhindern, wenn das Fragment nicht mehr lebt (und das nicht nur bei Okhttp).
Das Update: Prävention.
Wenn Sie sich den Fragmentlebenszyklus ansehen (weitere Informationen hier ), werden Sie feststellen, dass es onAttach(Context context)
und gibtonDetach()
Methoden. Diese werden aufgerufen, nachdem das Fragment zu einer Aktivität gehört und kurz bevor es aufhört.
Das bedeutet, dass wir diesen Rückruf verhindern können, indem wir ihn in der onDetach
Methode steuern .
@Override
public void onAttach(Context context) {
super.onAttach(context);
// Initialize HTTP we're going to use later.
http = new OkHttpClient.Builder().build();
}
@Override
public void onDetach() {
super.onDetach();
// We don't want to receive any more information about the current HTTP calls after this point.
// With Okhttp we can simply cancel the on-going ones (credits to https://github.com/square/okhttp/issues/2205#issuecomment-169363942).
for (Call call : http.dispatcher().queuedCalls()) {
call.cancel();
}
for (Call call : http.dispatcher().runningCalls()) {
call.cancel();
}
}
getActivity()
. Wie instanziieren Sie das Fragment? Hast du es in deiner layout.xml?