Tengo un Fragment
con un constructor que toma múltiples argumentos. Mi aplicación funcionó bien durante el desarrollo, pero en producción mis usuarios a veces ven este bloqueo:
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
Podría hacer un constructor vacío como sugiere este mensaje de error, pero eso no tiene sentido para mí desde entonces tendría que llamar a un método separado para terminar de configurar Fragment
.
Tengo curiosidad por saber por qué este bloqueo solo ocurre ocasionalmente. Tal vez estoy usando ViewPager
incorrectamente? Ejecuto todos los Fragment
correos yo mismo y los guardo en una lista dentro de Activity
. No uso FragmentManager
transacciones, ya que los ViewPager
ejemplos que he visto no lo requerían y todo parecía funcionar durante el desarrollo.
android
android-fragments
stkent
fuente
fuente
Fragment
subclase no declara ningún constructor en absoluto, entonces, de forma predeterminada, se hará implícitamente un constructor público vacío para usted (este es el comportamiento estándar de Java ). Usted no tiene que explícitamente declarar un constructor vacío a menos que también declararon otros constructores (por ejemplo, los que tienen argumentos).Respuestas:
Ellos si.
Realmente no deberías anular el constructor de todos modos. Debe tener un
newInstance()
método estático definido y pasar cualquier parámetro a través de argumentos (paquete)Por ejemplo:
Y, por supuesto, agarrando los args de esta manera:
Luego, creará una instancia de su administrador de fragmentos de la siguiente manera:
De esta manera, si se desconecta y vuelve a adjuntar, el estado del objeto se puede almacenar a través de los argumentos. Al igual que los paquetes adjuntos a las intenciones.
Motivo: lectura adicional
Pensé en explicar por qué a las personas que se preguntaban por qué.
Si marca: https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/Fragment.java
Verá que el
instantiate(..)
método en laFragment
clase llama alnewInstance
método:http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html#newInstance () Explica por qué, al crear una instancia, comprueba que el descriptor de acceso es
public
y que el cargador de clases permite el acceso a él.Es un método bastante desagradable en general, pero permite
FragmentManger
matar y recrearFragments
con estados. (El subsistema de Android hace cosas similares conActivities
).Clase de ejemplo
Me preguntan mucho acerca de llamar
newInstance
. No confunda esto con el método de clase. Este ejemplo de clase completa debería mostrar el uso.fuente
Como señaló CommonsWare en esta pregunta https://stackoverflow.com/a/16064418/1319061 , este error también puede ocurrir si está creando una subclase anónima de un Fragmento, ya que las clases anónimas no pueden tener constructores.
No hagas subclases anónimas de Fragment :-)
fuente
Sí, como puede ver, el paquete de soporte también crea instancias de los fragmentos (cuando se destruyen y se vuelven a abrir). Sus
Fragment
subclases necesitan un constructor público vacío, ya que esto es lo que llama el marco.fuente
super()
sería inútil, ya que la clase padre ha roto la regla del constructor público vacío. Entonces no, no necesita pasarsuper()
dentro de su constructor.Aquí está mi solución simple:
1 - Define tu fragmento
2 - Cree su nuevo fragmento y complete el parámetro
3 - ¡Disfrútalo!
Obviamente puede cambiar el tipo y la cantidad de parámetros. Rapido y Facil.
fuente