问题
I get this error message, when I open a closed App again via App-Change button:
Caused by: java.lang.InstantiationException: can't instantiate class com.*.FragmentContact$1; no empty constructor
I've found several tips about Inner-Classes and to make them static etc. But this FragmentContact is a public class in a *.java-file and has a public empty constructor. I'm using Google Maps Api v2 in this project and do a trick somewhere from the internet to setup my MapView. Look here:
@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;
}
When I cut this MapView-thing out everything work fine. Maybe someone can explain what I'm doing wrong.
My complete Stacktrace:
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
回答1:
But these FragmentContact is a public class in a *.java-file and has a public empty constructor.
The error is not complaining about FragmentContact
. It is complaining about the first inner class of FragmentContact
(FragmentContact$1
). You cannot have a Fragment
implemented as an inner class of anything, as it cannot be instantiated from outside the outer class. A static
inner class is fine.
回答2:
I've had this issue for ages and finally the comments on here have solved it for me. Nice information about the $1
meaning anonymous inner class.
Move your map initialisation to a new Public Class, e.g. MyMapFragment.java
. This will allow the fragment to be instantiated without the instance of
For those still not sure how to fix it. Write the code as follows (using the example code from the original question):
//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;
}
....
Create new MyMapFragment.java
so that it is no longer an inner class. This will allow the fragment to be created without it's outer class.
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);
}
}
}
Create MapLoadedCallback.java
to allow you to handle when the map has finished loading and to retrieve an instance of the loaded map object
public interface MapLoadedCallback {
void onLoaded(GoogleMap map);
}
回答3:
private Entity mEntity;
public YourFragment() {}
public static YourFragment getInstance(Entity mEntity) {
YourFragment fragment = new YourFragment();
fragment.mEntity = mEntity;
return fragment;
}
when you use this fragment,just call the static method getInstance
.
来源:https://stackoverflow.com/questions/16062923/fragment-instantiationexception-no-empty-constructor-google-maps-v2