Rzadko otrzymuję ten błąd podczas wykonywania wywołania interfejsu API.
java.lang.IllegalStateException: Fragment not attached to Activity
Próbowałem umieścić kod w isAdded()
metodzie, aby sprawdzić, czy fragment jest aktualnie dodawany do jej aktywności, ale nadal rzadko pojawia się ten błąd. Nie rozumiem, dlaczego nadal otrzymuję ten błąd. Jak mogę temu zapobiec?
Pokazuje błąd na linii
cameraInfo.setId(getResources().getString(R.string.camera_id));
Poniżej znajduje się przykładowe wywołanie interfejsu API, które tworzę.
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
Programista Androida
źródło
źródło
Odpowiedzi:
Ten błąd występuje z powodu połączonego wpływu dwóch czynników:
onResponse()
lubonError()
(które działają w głównym wątku), nie wiedząc, czyActivity
nadal jest na pierwszym planie, czy nie. JeśliActivity
zniknął (użytkownik przeszedł gdzie indziej),getActivity()
zwraca null.Response
jest wyrażona jako anonimowa klasa wewnętrzna, która domyślnie zawiera silne odniesienie doActivity
klasy zewnętrznej . Powoduje to klasyczny wyciek pamięci.Aby rozwiązać ten problem, zawsze powinieneś:
a także użyj
isAdded()
wonError()
metodzie:źródło
AsyncTask
s Volley z wewnątrz obiektuActivity
nie ma niezawodnego sposobu uniknięcia NPE. Zawsze istnieje szansa, że użytkownik może opuścić bieżący,Activity
podczas gdy jeden z wątków robi coś w tle, a następnie, gdy wątek zakończy się i /onPostExecute()
lubonResponse()
zostanie wywołany, nie maActivity
. Wszystko, co możesz zrobić, to sprawdzić zerowe odwołania w różnych punktach kodu, a to nie jest kuloodporne :)added
flagę logiczną i czy bieżącaActivity
instancja jest,null
czy nie.Cykl życia fragmentu jest bardzo złożony i pełen błędów, spróbuj dodać:
źródło
return mHost != null && mAdded;
- To właśnie jest w metodzie fragment.isAdded (). Myślałem, że mHost jest działaniem, jeśli go prześledzisz, ale wygląda na to, że mHost znajduje się wewnątrz FragmentActivity. Więc prawdopodobnie masz rację. Jakieś dodatki?Znalazłem bardzo proste rozwiązanie metoda isAdded () , która jest jedną z metod fragmentów służących do identyfikacji, czy ten bieżący fragment jest dołączony do jego działania, czy nie.
możemy tego użyć wszędzie w klasie fragmentów, takiej jak:
źródło
Wyjątek: java.lang.IllegalStateException: Fragment
DeadlineListFragment {ad2ef970} nie jest dołączone do działania
Kategoria: Cykl życia
Opis : podczas wykonywania czasochłonnej operacji w wątku w tle (np. AsyncTask) w międzyczasie utworzono nowy fragment i odłączono go od działania przed zakończeniem wątku w tle. Kod w wątku UI (np. OnPostExecute) wywołuje odłączony fragment, zgłaszając taki wyjątek.
Napraw rozwiązanie:
Anuluj wątek w tle podczas wstrzymywania lub zatrzymywania fragmentu
Użyj isAdded (), aby sprawdzić, czy fragment jest dołączony, a następnie wykonaj getResources () z działania.
źródło
mogę się spóźnić, ale mogę komuś pomóc ..... Najlepszym rozwiązaniem jest utworzenie globalnej instancji klasy aplikacji i wywołanie jej w konkretnym fragmencie, do którego nie jest dołączana Twoja aktywność
jak poniżej
Oto klasa aplikacji
źródło
Ten błąd może się zdarzyć, jeśli tworzysz wystąpienie fragmentu, którego w jakiś sposób nie można utworzyć:
W moim przypadku spotkałem się z tym, gdy próbowałem użyć:
źródło
W użyciu fragmentów
isAdded()
Zwróci wartość true, jeśli fragment jest obecnie dołączony do działania.Jeśli chcesz sprawdzić wewnątrz działania
Mam nadzieję, że to komuś pomoże
źródło
Przyjąłem następujące podejście do rozwiązania tego problemu. Utworzono nową klasę, która działa jako opakowanie dla metod działań takich jak ta
Teraz wszędzie tam, gdzie potrzebuję dostępu do zasobów z fragmentów lub działań, zamiast bezpośrednio wywoływać metodę, używam tej klasy. W przypadku, gdy działanie
context
nienull
jest, zwraca wartość aktywa, aw przypadku, gdycontext
jest równe null, przekazuje wartość domyślną (która jest również określana przez wywołującego funkcję).Ważny To nie jest rozwiązanie, jest to skuteczny sposób, aby z wdziękiem poradzić sobie z tą awarią. Chciałbyś dodać niektóre dzienniki w przypadkach, w których instancja aktywności ma wartość Null i spróbuj to naprawić, jeśli to możliwe.
źródło
Dzieje się tak, gdy fragment nie ma kontekstu, dlatego metoda getActivity () zwraca wartość null. sprawdź, czy używasz kontekstu, zanim go otrzymasz get lub czy działanie już nie istnieje. użyj kontekstu w fragment.onCreate i po odpowiedzi api zwykle powoduje ten problem
źródło
Czasami ten wyjątek jest spowodowany błędem w implementacji biblioteki obsługi. Ostatnio musiałem obniżyć wersję z 26.1.0 do 25.4.0, aby się go pozbyć.
źródło
Ten problem występuje za każdym razem, gdy wywołujesz kontekst, który jest niedostępny lub zerowy. Może to być sytuacja, gdy wywołujesz kontekst wątku głównego działania w wątku w tle lub kontekst wątku w tle w wątku głównym działania.
Na przykład zaktualizowałem mój udostępniony ciąg preferencji, taki jak następujący.
I zaraz po nim wywołał finish (). Teraz to, co robi, to to, że jako zatwierdzenie działa w głównym wątku i zatrzymuje wszelkie inne zatwierdzenia Async, jeśli nadchodzą, dopóki nie zakończy się. Więc jego kontekst jest żywy, dopóki zapis nie zostanie zakończony. W związku z tym poprzedni kontekst jest aktywny, powodując wystąpienie błędu.
Dlatego upewnij się, że kod został ponownie sprawdzony, jeśli jest jakiś kod, który ma ten problem z kontekstem.
źródło