Saya punya Fragment
dengan konstruktor yang membutuhkan banyak argumen. Aplikasi saya berfungsi dengan baik selama pengembangan, tetapi dalam produksi, pengguna saya terkadang melihat kerusakan ini:
android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment
make sure class name exists, is public, and has an empty constructor that is public
Saya bisa membuat konstruktor kosong seperti pesan kesalahan ini menyarankan, tapi itu tidak masuk akal bagi saya sejak itu saya harus memanggil metode terpisah untuk menyelesaikan pengaturan Fragment
.
Saya ingin tahu mengapa kecelakaan ini hanya terjadi sesekali. Mungkin saya menggunakan yang ViewPager
salah? Saya instantiate semua Fragment
s sendiri dan menyimpannya dalam daftar di dalam Activity
. Saya tidak menggunakan FragmentManager
transaksi, karena ViewPager
contoh yang saya lihat tidak memerlukannya dan semuanya tampak berfungsi selama pengembangan.
sumber
Fragment
subkelas Anda tidak mendeklarasikan konstruktor sama sekali, maka secara default konstruktor publik kosong secara implisit akan dibuat untuk Anda (ini adalah perilaku Java standar ). Anda tidak harus secara eksplisit mendeklarasikan konstruktor kosong kecuali jika Anda juga mendeklarasikan konstruktor lain (mis. Yang memiliki argumen).Jawaban:
Ya mereka melakukanya.
Anda seharusnya tidak benar-benar mengabaikan konstruktor. Anda harus memiliki
newInstance()
metode statis yang ditentukan dan meneruskan parameter apa pun melalui argumen (bundel)Sebagai contoh:
Dan tentu saja meraih argumen seperti ini:
Maka Anda akan instantiate dari manajer fragmen Anda seperti:
Dengan cara ini jika terlepas dan dilampirkan kembali keadaan objek dapat disimpan melalui argumen. Sama seperti bundel yang melekat pada Intents.
Alasan - Bacaan ekstra
Saya pikir saya akan menjelaskan mengapa orang bertanya-tanya mengapa.
Jika Anda memeriksa: https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/Fragment.java
Anda akan melihat
instantiate(..)
metode diFragment
kelas memanggilnewInstance
metode:http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html#newInstance () Menjelaskan alasannya, saat instantiasi memeriksa apakah accessornya
public
dan bahwa loader kelas memungkinkan akses ke sana.Ini adalah metode yang cukup jahat, tetapi memungkinkan
FragmentManger
untuk membunuh dan membuat ulangFragments
dengan status. (Subsistem Android melakukan hal serupa denganActivities
).Kelas Contoh
Saya banyak ditanya tentang menelepon
newInstance
. Jangan bingung ini dengan metode kelas. Contoh seluruh kelas ini harus menunjukkan penggunaannya.sumber
Seperti dicatat oleh CommonsWare dalam pertanyaan ini https://stackoverflow.com/a/16064418/1319061 , kesalahan ini juga dapat terjadi jika Anda membuat subkelas anonim dari Fragmen, karena kelas anonim tidak dapat memiliki konstruktor.
Jangan membuat subclass anonim Fragmen :-)
sumber
Ya, seperti yang Anda lihat paket dukungan juga instantiates fragmen (ketika mereka dihancurkan dan dibuka kembali).
Fragment
Subclass Anda memerlukan konstruktor kosong publik karena ini adalah apa yang disebut oleh framework.sumber
super()
akan sia-sia, karena kelas induk telah melanggar aturan konstruktor publik kosong. Jadi tidak, Anda tidak perlu melewatisuper()
bagian dalam konstruktor Anda.Inilah solusi sederhana saya:
1 - Tentukan fragmen Anda
2 - Buat fragmen baru Anda dan isi parameter
3 - Nikmati saja!
Jelas Anda dapat mengubah jenis dan jumlah parameter. Cepat dan mudah.
sumber