2013-04-17 12 views
16

ottengo questo messaggio di errore, quando ho aperto ancora una volta un App chiuso tramite App-pulsante Cambia:Frammento - InstantiationException: nessun vuoto Costruttore -> Google Maps v2?

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

Ho trovato diversi suggerimenti in merito a Inner-Classes e di renderli ecc statico Ma questo è un FragmentContact public classe in un * .java-file e ha un costruttore vuoto pubblico. Sto usando Google Maps Api v2 in questo progetto e faccio un trucco da qualche parte da Internet per configurare il mio MapView. Guarda qui:

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

    } 

Quando ho tagliato questo oggetto di MapView tutto funziona correttamente. Forse qualcuno può spiegare cosa sto sbagliando.

mia completa 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

la prego di pubblicare il tuo stacktrace completa? –

risposta

29

Ma questi FragmentContact è una classe pubblica in un .java-file * e ha un costruttore pubblico vuoto.

L'errore non si è lamentato di FragmentContact. Si lamenta della prima classe interna di FragmentContact (FragmentContact$1). Non è possibile avere un Fragment implementato come una classe interna di qualcosa, poiché non può essere istanziato dall'esterno della classe esterna. Una classe interna static va bene.

+1

Scusa, colpa mia. Non ho riconosciuto la classe interiore anonima perché ho pensato a classi interne non anonime tutto il tempo. Hai assolutamente ragione. Sovrascrivo il 'pubblico vuoto onActivityCreated (Bundle savedInstanceState)' e quindi uso una classe interna anonima. Vergogna su di me ... – Osiriz

+5

@Osiriz: Il '$ 1' significa che è una classe interna anonima - altrimenti, sarebbe stato' $ QualunqueCosìLaClasseInn ". Detto questo, mi mancava quando leggevo il tuo codice originariamente, pensando che fosse in qualche altro file. – CommonsWare

+3

Devo confessare che non conoscevo il significato di '$ 1' nello stacktrace fino ad ora. Molti carri armati! – Osiriz

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

quando si utilizza questo frammento, è sufficiente chiamare il metodo statico getInstance.

0

Ho avuto questo problema per anni e, infine, i commenti qui hanno risolto per me. Belle informazioni sul $1 che significa classe interiore anonima.

Sposta l'inizializzazione della mappa in una nuova Classe pubblica, ad es. MyMapFragment.java. Ciò consentirà l'istanziazione del frammento senza l'istanza di

Per coloro che non sono ancora sicuri su come risolverlo. Scrivere il codice come segue (utilizzando il codice di esempio dalla domanda iniziale):

//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 nuovo MyMapFragment.java in modo che non è più una classe interna. Ciò consentirà di creare il frammento senza la sua classe esterna.

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

Crea MapLoadedCallback.java per consentire di gestire quando la mappa ha terminato il caricamento e per recuperare un'istanza dell'oggetto mappa caricata

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

Non sarà d'aiuto ... perché questa non è una classe interiore statica ... L'unica differenza è che questo non è anonimo ... – Selvin

+0

@ Silvin: Non sono sicuro di cosa intendi. Il problema è stato risolto a causa del fatto che la classe non è più anonima. Se fosse statico, il problema non sarebbe mai esistito in quanto una classe interna statica avrebbe potuto essere risolta correttamente. La classe interna non statica –

+0

non ha ancora un costruttore vuoto (al di fuori dell'ambito della classe esterna) ... non puoi chiamare 'new Outer.Inner()' (sì, puoi chiamare 'new Inner()' all'interno di 'Outer' 'Fragment.instantiate'can't fare questo) - in altre parole: le basi di java ... l'istanza della classe non statica interna non può essere inizializzata senza l'istanza di classe esterna – Selvin

Problemi correlati