tipos sobrecargado por parametros ejercicios ejemplos defecto copia constructores android constructor fragment instantiationexception

android - sobrecargado - Fragmento-Excepción de excepción: no hay un Constructor vacío-> Google Maps v2?



ejercicios de constructores en java (3)

Recibo este mensaje de error, cuando abro una aplicación cerrada de nuevo a través del botón de cambio de aplicación:

Caused by: java.lang.InstantiationException: can''t instantiate class com.*.FragmentContact$1; no empty constructor

He encontrado varios consejos sobre Clases internas y para hacerlas estáticas, etc. Pero este FragmentContact es una clase pública en un archivo * .java y tiene un constructor vacío público . Estoy utilizando Google Maps Api v2 en este proyecto y hago un truco desde algún lugar de Internet para configurar mi MapView. Mira aquí:

@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_contact, null); try { MapsInitializer.initialize(this.getActivity().getApplicationContext()); } catch (GooglePlayServicesNotAvailableException e) { e.printStackTrace(); } fragment = new SupportMapFragment() { @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); mMap = fragment.getMap(); if (mMap != null) { setupMap(); } } }; getFragmentManager().beginTransaction().replace(R.id.fragment_orte_map_parent, fragment).commit(); return v; }

Cuando corte esta cosa de MapView todo funciona bien. Tal vez alguien pueda explicar lo que estoy haciendo mal.

Mi Stacktrace completo:

FATAL EXCEPTION: main java.lang.RuntimeException: Unable to start activity ComponentInfo{com.*/com.*.MainActivity}: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment com.*.FragmentContact$1: make sure class name exists, is public, and has an empty constructor that is public at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2307) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2357) at android.app.ActivityThread.access$600(ActivityThread.java:153) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1247) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:5226) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562) at dalvik.system.NativeStart.main(Native Method) Caused by: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment com.*.FragmentContact$1: make sure class name exists, is public, and has an empty constructor that is public at android.support.v4.app.Fragment.instantiate(Fragment.java:405) at android.support.v4.app.FragmentState.instantiate(Fragment.java:97) at android.support.v4.app.FragmentManagerImpl.restoreAllState(FragmentManager.java:1767) at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:208) at com.*.MainActivity.onCreate(MainActivity.java:20) at android.app.Activity.performCreate(Activity.java:5104) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2261) ... 11 more Caused by: java.lang.InstantiationException: can''t instantiate class com.*.FragmentContact$1; no empty constructor at java.lang.Class.newInstanceImpl(Native Method) at java.lang.Class.newInstance(Class.java:1319) at android.support.v4.app.Fragment.instantiate(Fragment.java:394) ... 18 more


Pero este FragmentContact es una clase pública en un archivo * .java y tiene un constructor vacío público.

El error no es quejarse de FragmentContact . Se queja de la primera clase interna de FragmentContact ( FragmentContact$1 ). No puedes tener un Fragment implementado como una clase interna de nada, ya que no puede ser instanciado desde fuera de la clase externa. Una clase interna static está bien.


He tenido este problema por años y finalmente los comentarios aquí lo resolvieron por mí. Buena información sobre la clase interna anónima que significa $1 .

Mueva la inicialización de su mapa a una nueva clase pública, por ejemplo, MyMapFragment.java . Esto permitirá que el fragmento sea instanciado sin la instancia de

Para aquellos que todavía no están seguros de cómo solucionarlo. Escriba el código de la siguiente manera (usando el código de ejemplo de la pregunta original):

//Existing code to instantiate map @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_contact, null); try { MapsInitializer.initialize(this.getActivity().getApplicationContext()); } catch (GooglePlayServicesNotAvailableException e) { e.printStackTrace(); } fragment = new MyMapFragment(); //added callback for catching when the map has finished loading mapFragment.setLoadedCallback(new MapLoadedCallback() { @Override public void onLoaded(GoogleMap map) { mMap = map; } }); getFragmentManager().beginTransaction().replace(R.id.fragment_orte_map_parent, fragment).commit(); return v; } ....

Crea un nuevo MyMapFragment.java para que ya no sea una clase interna. Esto permitirá que el fragmento se cree sin su clase externa.

public class MyMapFragment extends SupportMapFragment { GoogleMap mMap; public MyMapFragment() { } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); mMap = fragment.getMap(); if (mMap != null) { mCallback.onLoaded(mMap); } } }

Cree MapLoadedCallback.java para permitirle manejar cuando el mapa haya terminado de cargarse y recuperar una instancia del objeto de mapa cargado

public interface MapLoadedCallback { void onLoaded(GoogleMap map); }


private Entity mEntity; public YourFragment() {} public static YourFragment getInstance(Entity mEntity) { YourFragment fragment = new YourFragment(); fragment.mEntity = mEntity; return fragment; }

cuando use este fragmento, simplemente llame al método estático getInstance .