2013-04-17 6 views
16

Ich erhalte diese Fehlermeldung, wenn ich eine geschlossene App wieder über App-Schaltfläche Ändern öffnen:Fragment - InstantiationException: kein leerer Konstruktor -> Google Maps v2?

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

ich einige Tipps zu Inner-Klassen gefunden haben und sie statisch usw. zu machen, aber dies ist ein FragmentContact public Klasse in einem * .java-Datei und hat einen öffentlichen leeren Konstruktor. Ich verwende Google Maps Api v2 in diesem Projekt und mache einen Trick irgendwo aus dem Internet, um mein MapView einzurichten. Schau mal hier:

@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; 

    } 

Wenn ich dieses MapView-Ding ausschneiden klappt alles gut. Vielleicht kann jemand erklären, was ich falsch mache.

Meine komplette Stacktrace:

04-17 16:15:22.115: E/AndroidRuntime(22182): FATAL EXCEPTION: main 
04-17 16:15:22.115: E/AndroidRuntime(22182): 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 
04-17 16:15:22.115: E/AndroidRuntime(22182): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2307) 
04-17 16:15:22.115: E/AndroidRuntime(22182): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2357) 
04-17 16:15:22.115: E/AndroidRuntime(22182): at android.app.ActivityThread.access$600(ActivityThread.java:153) 
04-17 16:15:22.115: E/AndroidRuntime(22182): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1247) 
04-17 16:15:22.115: E/AndroidRuntime(22182): at android.os.Handler.dispatchMessage(Handler.java:99) 
04-17 16:15:22.115: E/AndroidRuntime(22182): at android.os.Looper.loop(Looper.java:137) 
04-17 16:15:22.115: E/AndroidRuntime(22182): at android.app.ActivityThread.main(ActivityThread.java:5226) 
04-17 16:15:22.115: E/AndroidRuntime(22182): at java.lang.reflect.Method.invokeNative(Native Method) 
04-17 16:15:22.115: E/AndroidRuntime(22182): at java.lang.reflect.Method.invoke(Method.java:511) 
04-17 16:15:22.115: E/AndroidRuntime(22182): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795) 
04-17 16:15:22.115: E/AndroidRuntime(22182): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562) 
04-17 16:15:22.115: E/AndroidRuntime(22182): at dalvik.system.NativeStart.main(Native Method) 
04-17 16:15:22.115: E/AndroidRuntime(22182): 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 
04-17 16:15:22.115: E/AndroidRuntime(22182): at android.support.v4.app.Fragment.instantiate(Fragment.java:405) 
04-17 16:15:22.115: E/AndroidRuntime(22182): at android.support.v4.app.FragmentState.instantiate(Fragment.java:97) 
04-17 16:15:22.115: E/AndroidRuntime(22182): at android.support.v4.app.FragmentManagerImpl.restoreAllState(FragmentManager.java:1767) 
04-17 16:15:22.115: E/AndroidRuntime(22182): at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:208) 
04-17 16:15:22.115: E/AndroidRuntime(22182): at com.*.MainActivity.onCreate(MainActivity.java:20) 
04-17 16:15:22.115: E/AndroidRuntime(22182): at android.app.Activity.performCreate(Activity.java:5104) 
04-17 16:15:22.115: E/AndroidRuntime(22182): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080) 
04-17 16:15:22.115: E/AndroidRuntime(22182): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2261) 
04-17 16:15:22.115: E/AndroidRuntime(22182): ... 11 more 
04-17 16:15:22.115: E/AndroidRuntime(22182): Caused by: java.lang.InstantiationException: can't instantiate class com.*.FragmentContact$1; no empty constructor 
04-17 16:15:22.115: E/AndroidRuntime(22182): at java.lang.Class.newInstanceImpl(Native Method) 
04-17 16:15:22.115: E/AndroidRuntime(22182): at java.lang.Class.newInstance(Class.java:1319) 
04-17 16:15:22.115: E/AndroidRuntime(22182): at android.support.v4.app.Fragment.instantiate(Fragment.java:394) 
04-17 16:15:22.115: E/AndroidRuntime(22182): ... 18 more 
+1

könnten Sie bitte posten Sie Ihre vollständige Stacktrace abzurufen? –

Antwort

29

Aber diese FragmentContact ist eine öffentliche Klasse in einer * .java-Datei und verfügt über einen öffentlichen leeren Konstruktor.

Der Fehler beschwert sich nicht über FragmentContact. Es beschwert sich über die erste innere Klasse von FragmentContact (FragmentContact$1). Sie können keine als innere Klasse von irgendetwas implementiert haben, da sie nicht von außerhalb der äußeren Klasse instanziiert werden kann. Eine static innere Klasse ist in Ordnung.

+1

Entschuldigung, meine Schuld. Ich habe die anonyme innere Klasse nicht erkannt, weil ich ständig an nicht-anonyme innere Klassen gedacht habe. Du hast absolut recht. Ich überschreibe 'public void onActivityCreated (Bundle savedInstanceState)' und verwende eine anonyme innere Klasse. Schande über mich ... – Osiriz

+5

@Osiriz: Die '$ 1 'bedeutet, dass es eine anonyme innere Klasse ist - andernfalls wäre es' $ WhateverYouCalledTheInnerClass'. Davon abgesehen habe ich es verpasst, als ich den Code ursprünglich gelesen habe und gedacht habe, dass er in einer anderen Datei gespeichert ist. – CommonsWare

+3

Ich muss gestehen, dass ich bis jetzt nicht einmal die Bedeutung von $ 1 im Stacktrace kannte. Viele Panzer! – Osiriz

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

, wenn Sie dieses Fragment verwenden, rufen Sie einfach die statische Methode getInstance.

0

Ich habe dieses Problem seit Ewigkeiten und endlich die Kommentare hier haben es für mich gelöst. Schöne Informationen über die $1 Bedeutung anonyme innere Klasse.

Verschieben Sie die Karteninitialisierung in eine neue öffentliche Klasse, z. MyMapFragment.java. Dies ermöglicht die Instanziierung des Fragments ohne die Instanz

Für diejenigen, die immer noch nicht sicher, wie es zu beheben ist. Schreiben Sie den Code wie folgt (die Beispiel-Code aus der ursprünglichen Frage verwenden):

//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; 
} 
.... 

Neuen MyMapFragment.java so dass es nicht mehr eine innere Klasse ist. Dadurch kann das Fragment ohne seine äußere Klasse erstellt werden.

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); 
     } 
    } 
}  

erstellen MapLoadedCallback.java, damit Sie die Karte zu handhaben, wenn fertig geladen ist und eine Instanz des geladenen Kartenobjekt

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

Es wird nicht helfen ... wie dies ist nicht statische innere Klasse ... Der einzige Unterschied ist, dass dieser nicht anonym ist ... – Selvin

+0

@Selvin: Ich bin mir nicht sicher, was du meinst. Das Problem wurde behoben, da die Klasse nicht mehr anonym ist. Wenn es statisch wäre, hätte das Problem überhaupt nicht bestanden, da eine statische innere Klasse korrekt aufgelöst werden könnte. –

+0

innere nicht statische Klasse hat immer noch keinen leeren Konstruktor (außerhalb des äußeren Klassenbereichs) ... Sie können 'new Outer.Inner()' nicht aufrufen (ja, Sie können 'new Inner()' innerhalb von 'Outer' aufrufen 'Fragment.instantiate' kann das nicht tun - mit anderen Worten: javas Grundlagen ... innere nicht statische Klasseninstanz kann nicht ohne äußere Klasseninstanz initialisiert werden – Selvin