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
.