18

ho fatto un semplice Attività che mostra un semplice ListFragment come di seguito:Molto semplice codice, ma ha ricevuto l'errore "di attività è stata distrutta" quando l'uso Frammento

La mia attività:

public class MyActivity extends FragmentActivity { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
      FragmentManager fragMgr = getSupportFragmentManager(); 

      FirstFragment list = new FirstFragment(); 
      fragMgr.beginTransaction().add(android.R.id.content, list).commit(); 
    } 

} 

mio ListFragment:

public class FirstFragment extends ListFragment{ 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     inflater.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     View view = inflater.inflate(R.layout.main, null); 
     return view; 
    } 


    @Override 
    public void onActivityCreated(Bundle savedInstanceState) { 
     super.onActivityCreated(savedInstanceState); 

     String listContent[] = {"Larry", "Moe", "Curly"}; 
     setListAdapter(new ArrayAdapter<String>(getActivity(), R.layout.list_item, listContent)); 
    } 
    ... 
} 

Quando comincio la mia app, ho ottenuto messaggio di errore:

java.lang.IllegalStateException: Activity has been destroyed 
E/AndroidRuntime( 947): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2496) 
E/AndroidRuntime( 947): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512) 
E/AndroidRuntime( 947): at android.app.ActivityThread.access$2200(ActivityThread.java:119) 
E/AndroidRuntime( 947): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863) 
E/AndroidRuntime( 947): at android.os.Handler.dispatchMessage(Handler.java:99) 
E/AndroidRuntime( 947): at android.os.Looper.loop(Looper.java:123) 
E/AndroidRuntime( 947): at android.app.ActivityThread.main(ActivityThread.java:4363) 
E/AndroidRuntime( 947): at java.lang.reflect.Method.invokeNative(Native Method) 
... 

Si lamenta che attività è stata distrutta, Perchè ???

P.S. main.xml:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:paddingLeft="8dp" 
    android:paddingRight="8dp"> 

    <Button 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="next" /> 

    <ListView 
    android:id="@android:id/list" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:background="#00FF00" 
    android:layout_weight="1" 
    android:drawSelectorOnTop="false" /> 

    <TextView 
    android:id="@android:id/empty" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:background="#FF0000" 
    android:text="No data" /> 
</LinearLayout> 

risposta

28

ho capito me stesso, è perché ho perso la super.onCreate(savedInstanceState); nel mio metodo di attività onCreate(). Dopo averlo aggiunto, le cose vanno bene.

+1

Si noti che è possibile accettare la risposta come la risposta migliore –

+6

Se qualcuno può spiegare la ragione profonda, accetterò la migliore non la mia :) –

+1

Nel mio caso stavo chiamando super.onCreate (savedInstanceState); dopo aver aggiunto il frammento. – Ankit

2

Giusto per essere sicuro che sto vedendo questo, MyActivity è l'attività che stai cercando di avviare e quindi aggiungere un'istanza di FirstFragment, giusto?

Immediatamente vedo due cose che avete bisogno di guardare

1) nella vostra attività avete mai chiamata setContentView() o super.onCreate(). La prima chiamata potrebbe essere un grosso problema per te perché significa che il tuo layout non è mai stato gonfiato, e quindi la variabile R non esiste

2) MyActivity deve avere il proprio file di layout xml, che non avere.

+0

Ciao, non penso che un'attività debba avere un file di layout, ad esempio, il mio codice funziona dopo aver aggiunto super.onCreate (...), la mia attività ospita solo un frammento e il frammento gonfierà un layout in mostra, non l'attività. –

+0

È possibile poiché non ho usato molto il pacchetto di supporto. La maggior parte del mio sviluppo è su Honeycomb con layout a più riquadri. Stavo solo guardando i documenti API e penso che tu abbia ragione. Grazie per aver segnalato questo! –

+0

Nessun problema, sono anche nuovo per il pacchetto di supporto, comincio a imparare il frammento solo da oggi :) –

4

di dare una spiegazione:

Il quadro crea la Activity e chiede Activity.onCreate().

Activity.onCreate() in qualche modo si collegherà allo FragmentManager per informarlo sull'attività di hosting. Activity.onDestroy() lo annullerà di nuovo.

Ora si estende Activity e si sostituisce onCreate(). È possibile effettuare chiamate a FragmentManager senza chiamare fino a Activity.onCreate(). L'intera logica di registrazione spiegata sopra non viene eseguita. Lo FragmentManager pertanto non sa nulla sull'attività e presuppone che sia già stato distrutto e genera l'eccezione con il messaggio di errore fuorviante.

68

Ho anche affrontato un problema simile.
Mi sono reso conto che ciò è accaduto perché l'attività veniva distrutta mentre il FragmentTransaction stava per ottenere .commit().

Una soluzione a questo era per verificare se il è vero o no.

if (!isFinishing()) { 
    FragmentTransaction ft = getSupportFragmentManager() 
    .beginTransaction(); 
    ft.replace(SOME_RES_ID, myFragmentInstance); 
    ft.commit(); 
} 
+0

Grazie ha funzionato per me! È venuto qui attraverso una [discussione su Github] (https://github.com/JakeWharton/ActionBarSherlock/issues/1031). Grazie per la condivisione. –

1

quello che ho fatto è immediatamente dopo l'impegno che io chiamo

fragmentManager.executePendingTransactions();

e non tentare mai di commettere dopo onpause() chiamato

Leggi questo Artical Fragment Transactions & Activity State Loss

10

Ho affrontato lo stesso problema e non è in grado di risolverlo. Evento che ho aggiunto anche isFinishing(). ma senza fortuna.

quindi ho aggiunto un altro controllo isDestroyed() e funziona correttamente ora.

if (!isFinishing() && !isDestroyed()) { 
    FragmentTransaction ft = getSupportFragmentManager() 
    .beginTransaction(); 
    ft.replace(LAYOUT_ID, myFragmentInstance); 
    ft.commit(); 
} 
+1

Si noti che 'onDestroyed()' è stato aggiunto al livello API 17. – Gira

0

super.onCreate (savedInstanceState) chiamerà onCreate metodo FragmentActivity, che chiamerà mFragments.attachHost(null /*parent*/);

Questa frase sarà assegnare un valore a mHost in FragmentController, quando chiamate FragmentTransaction.commit(),

Nel metodo enqueueAction(), ha questa frase

if (mDestroyed || mHost == null) { 
     throw new IllegalStateException("Activity has been destroyed"); 
} 

Quindi, se non avete chiamare super.onCreate (savedInstanceState) prima di commettere un fragmentTransaction, si ottiene questa eccezione perché mHost è nullo

0

Se qualcuno venire attraverso simile tipo di problema:

stavo affrontando nello stesso tempo di problema, ma nel mio caso dall'Attività principale stavo chiamando a Fragment1 e quindi se l'utente fa clic su Fragment1 Layout voglio lanciare un altro Fragment2 Layout.

Sono stato in grado di avviare Fragment1 dall'attività principale ma Fragment1 a Fragment2 non funzionava eccezionalmente come "L'attività è stata distrutta".

Ho risolto il problema precedente mantenendo l'oggetto FragmentManager come statico nella classe MainActivity. private static FragmentManager mfragmentManager = null;

chiamare su entrambi i frammenti utilizzando lo stesso oggetto sopra, ha risolto il problema.

Di seguito è riportato il mio codice di commutazione Fragment da Attività principale.

public void switchToFragment(String fragmentName){ 
     Fragment fragment = null; 
     switch (fragmentName) { 
      case "Fragment1":{ 
       fragment = new Fragment1(); 
       break; 
      } 
      case "Fragment2": { 
       fragment = new Fragment2(); 
       break; 
      } 
     } 

     FragmentTransaction transaction = mfragmentManager.beginTransaction(); 
     transaction.replace(R.id.fragment_container, fragment); 
     transaction.commit(); 
    } 
1

ancora male, perché ha ricevuto l'errore “di attività è stata distrutta”

ava.lang.IllegalStateException: Activity has been destroyed fragmentTransaction.commitAllowingStateLoss(); 

Quindi la mia soluzione è aggiungere controllare if (!isFinishing()&&!isDestroyed())

if (!isFinishing()&&!isDestroyed()) { 
         fragmentTransaction.commitAllowingStateLoss(); 
        } 
       } 
Problemi correlati