Saya jarang mendapatkan kesalahan ini saat melakukan panggilan API.
java.lang.IllegalStateException: Fragment not attached to Activity
Saya mencoba memasukkan kode ke dalam isAdded()
metode untuk memeriksa apakah fragmen saat ini ditambahkan ke aktivitasnya tetapi saya masih jarang mendapatkan kesalahan ini. Saya gagal memahami mengapa saya masih mendapatkan kesalahan ini. Bagaimana saya bisa mencegahnya?
Ini menunjukkan kesalahan pada baris-
cameraInfo.setId(getResources().getString(R.string.camera_id));
Di bawah ini adalah contoh panggilan api yang saya buat.
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
Pengembang Android
sumber
sumber
Jawaban:
Kesalahan ini terjadi karena efek gabungan dari dua faktor:
onResponse()
atauonError()
(yang bekerja pada utas utama) tanpa mengetahui apakahActivity
masih di latar depan atau tidak. JikaActivity
hilang (pengguna menavigasi ke tempat lain),getActivity()
mengembalikan nol.Response
dinyatakan sebagai kelas dalam anonim, yang secara implisit memegang referensi kuat keActivity
kelas luar . Ini menghasilkan kebocoran memori klasik.Untuk mengatasi masalah ini, Anda harus selalu melakukan:
dan juga, gunakan
isAdded()
dalamonError()
metode ini juga:sumber
AsyncTask
s dari dalamActivity
, tidak ada cara mudah untuk menghindari NPE. Selalu ada kemungkinan bahwa pengguna dapat menavigasi menjauh dari saat iniActivity
sementara salah satu utas sedang melakukan sesuatu di latar belakang, dan kemudian ketika utas selesai danonPostExecute()
atauonResponse()
dipanggil, tidak adaActivity
. Yang dapat Anda lakukan adalah melakukan pengecekan untuk referensi nol di berbagai titik dalam kode Anda, dan itu bukan antipeluru :)added
bendera boolean dan apakahActivity
instance saat ini adalahnull
atau tidak.Siklus hidup fragmen sangat kompleks dan penuh bug, coba tambahkan:
sumber
return mHost != null && mAdded;
- Itulah yang ada di dalam metode fragment.isAdded (). Saya pikir mHost adalah sebuah Kegiatan jika Anda melacaknya, tetapi sepertinya mHost ada di dalam FragmentActivity. Jadi, mungkin Anda benar. Adakah tambahan?Saya Menemukan Solusi Sangat Sederhana yang Diisi () metode yang merupakan salah satu metode fragmen untuk mengidentifikasi bahwa fragmen saat ini melekat pada Aktivitasnya atau tidak.
kita dapat menggunakan ini seperti di mana saja di kelas fragmen seperti:
sumber
Pengecualian: java.lang.IllegalStateException: Fragment
DeadlineListFragment {ad2ef970} tidak dilampirkan ke Activity
Kategori: Siklus Hidup
Deskripsi : Saat melakukan operasi yang memakan waktu di utas latar (mis., AsyncTask), sementara itu Fragmen baru telah dibuat, dan dilepaskan ke Aktivitas sebelum utas latar belakang selesai. Kode di utas UI (misalnya, onPostExecute) memanggil Fragment yang terpisah, melempar pengecualian tersebut.
Perbaiki solusi:
Batalkan utas latar saat menjeda atau menghentikan Fragmen
Gunakan isAdded () untuk memeriksa apakah fragmen dilampirkan dan kemudian untuk getResources () dari aktivitas.
sumber
saya mungkin terlambat tetapi dapat membantu seseorang ..... Solusi terbaik untuk ini adalah membuat instance kelas aplikasi global dan menyebutnya dalam fragmen khusus di mana aktivitas Anda tidak dilampirkan
seperti di bawah ini
Ini adalah kelas aplikasi
sumber
Kesalahan ini dapat terjadi jika Anda membuat sebuah fragmen yang entah bagaimana tidak dapat dipakai:
Dalam kasus saya, saya telah bertemu ini ketika saya mencoba menggunakan:
sumber
Sedang digunakan Fragment
isAdded()
Ini akan mengembalikan true jika fragmen saat ini dilampirkan ke Aktivitas.Jika Anda ingin memeriksa bagian dalam Activity
Semoga ini bisa membantu seseorang
sumber
Saya mengadopsi pendekatan berikut untuk menangani masalah ini. Menciptakan kelas baru yang bertindak sebagai pembungkus untuk metode aktivitas seperti ini
Sekarang di mana pun saya perlu mengakses sumber daya dari fragmen atau kegiatan, alih-alih langsung memanggil metode, saya menggunakan kelas ini. Jika aktivitasnya
context
tidaknull
mengembalikan nilai aset dan jikacontext
bernilai nol, akan melewati nilai default (yang juga ditentukan oleh penelepon fungsi).Penting Ini bukan solusi, ini adalah cara yang efektif di mana Anda dapat menangani kecelakaan ini dengan anggun. Anda ingin menambahkan beberapa log jika Anda mendapatkan instance aktivitas sebagai nol dan coba memperbaikinya, jika memungkinkan.
sumber
ini terjadi ketika fragmen tidak memiliki konteks, sehingga metode getActivity () mengembalikan nol. periksa apakah Anda menggunakan konteksnya sebelum Anda mendapatkannya, atau jika Activity tidak ada lagi. gunakan konteks di fragment.onCreate dan setelah respon api biasanya kasus masalah ini
sumber
Terkadang pengecualian ini disebabkan oleh bug dalam implementasi perpustakaan dukungan. Baru-baru ini saya harus menurunkan versi dari 26.1.0 ke 25.4.0 untuk menyingkirkannya.
sumber
Masalah ini terjadi setiap kali Anda memanggil konteks yang tidak tersedia atau nol saat Anda menyebutnya. Ini bisa menjadi situasi ketika Anda memanggil konteks utas aktivitas utama pada utas latar belakang atau konteks utas latar belakang pada utas aktivitas utama.
Misalnya, saya memperbarui string preferensi bersama saya seperti berikut.
Dan disebut finish () tepat setelah itu. Sekarang apa yang dilakukannya adalah bahwa commit berjalan di utas utama dan menghentikan komitmen Async lainnya jika datang sampai selesai. Jadi konteksnya hidup sampai penulisan selesai. Karenanya konteks sebelumnya adalah langsung, menyebabkan kesalahan terjadi.
Jadi pastikan kode Anda diperiksa ulang jika ada beberapa kode yang memiliki masalah konteks ini.
sumber