2010-03-11 11 views
55

Ho un'attività A con android:launchMode="singleTop" nel manifest.Nuovo intent() avvia una nuova istanza con Android: launchMode = "singleTop"

Se vado a Attività B, C, e D ci devo scorciatoie menu per tornare al mio applicazioni attività delle radici (A).

Il codice simile a questo:

Intent myIntent = new Intent(getBaseContext(), MainActivity.class); 
startActivity(myIntent); 

Tuttavia, invece di tornare all'istanza già esistente A della mia MainActivity.class si crea una nuova istanza -> va a onCreate() invece di onNewIntent().

Questo non è il comportamento previsto, giusto?

risposta

65

Questo dovrebbe fare il trucco.

<activity ... android:launchMode="singleTop" /> 

Quando si crea l'intento di avviare l'utilizzo app:

Intent intent= new Intent(context, YourActivity.class); 
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP); 

Questo è che dovrebbe essere necessario.

+2

Questo non funziona per me. :(le righe di codice riportate di seguito funzionano correttamente. Intent myIntent = new Intent (getBaseContext(), MainActivity.class); myIntent.setFlags (Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity (myIntent); –

14

Citazione dal documentation:

Lo "standard" e "singleTop" modalità differiscono tra loro in un solo rispetto: Ogni volta che c'è di nuovo intento per un'attività "standard", un nuovo L'istanza della classe viene creata per rispondere a tale intenzione. Ogni istanza gestisce un singolo intent. Analogamente, una nuova istanza di un'attività "singleTop" può anche essere creata per gestire un nuovo intento . Tuttavia, se l'attività bersaglio ha già un'istanza esistente di dell'attività nella parte superiore della sua pila, tale istanza riceverà nuovo intento (in onNewIntent() call); una nuova istanza non è stata creata.

Non sono sicuro al 100% che cosa significa "ha già un'istanza dell'attività in cima allo stack", ma forse l'attività non soddisfa questa condizione.

singleTask o singleInstance lavoro per voi? O forse potresti provare a impostare FLAG_ACTIVITY_SINGLE_TOP sull'intento che stai creando per vedere se questo fa la differenza, anche se non penso che lo farà.

+0

Significa che lo stack di attività (stack di applicazioni) attualmente attivo ha un'istanza di tale attività in primo piano (ad esempio un'attività sta avviando un'altra copia della stessa attività quando è attiva). Altre istanze della stessa attività possono esistere in altre attività (applicazioni). –

+0

Quindi, se la mia volontà è quella di avviare una nuova istanza di attività nello stesso processo, ma ho già FOCUSATO su un'istanza precedente di tale attività, come potrei farlo? – rayman

+0

@rayman usa la modalità standard, suppongo? dice nel documento "Ogni volta che c'è un nuovo intento per un'attività" standard ", viene creata una nuova istanza della classe per rispondere a tale intento." –

27

Che in realtà ha funzionato per me, alla fine, è stato questo:

Intent myIntent = new Intent(getBaseContext(), MainActivity.class); 
myIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
startActivity(myIntent); 
+0

Works a treat, thanks –

+0

È possibile che si verifichino alcuni [comportamenti imprevisti] (https://github.com/cleverua/android_startup_activity) con attività singleTop. [Possibile soluzione] (https://github.com/cleverua/android_startup_activity) –

+0

Ottimo! Grazie, signore. :) –

6

È possibile tornare alla stessa istanza esistente di attività con android:launchMode="singleInstance"

nel manifesto. Quando si ritorna a A da B, potrebbe essere necessario finish() per distruggere B.

1

In primo luogo, è possibile esaminare la struttura dello stack. Per la modalità di avvio: singleTop
Se un'istanza della stessa attività si trova già sopra lo stack delle attività, questa istanza verrà riutilizzata per rispondere all'intento.

Tutte le attività sono in possesso della pila ("first in last out"), quindi se la vostra attività in corso è in cima alla pila e se si definisce nel manifest.file come singleTop

android:name=".ActivityA" 
android:launchMode="singleTop" 

se sei nel ActivityA ricrea l'attività che non entrerà onCreate riprenderà onNewIntent() e puoi vedere creando una notifica Non: Se non implementi onNewIntent (Intent) non otterrai nuovi intenti.

Intent activityMain = new Intent(ActivityA.this, 
         ActivityA.class); 

       activityMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 
         | Intent.FLAG_ACTIVITY_SINGLE_TOP); 
       startActivity(activityMain); 




    @Override 
     protected void onNewIntent(Intent intent) { 

      super.onNewIntent(intent); 

      notify("onNewIntent"); 
     } 

     private void notify(String methodName) { 

      String name = this.getClass().getName(); 
      String[] strings = name.split("\\."); 

      Notification noti = new Notification.Builder(this) 
        .setContentTitle(methodName + "" + strings[strings.length - 1]) 
        .setAutoCancel(true).setSmallIcon(R.drawable.ic_launcher) 
        .setContentText(name).build(); 
      NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); 
      notificationManager.notify((int) System.currentTimeMillis(), noti); 

     } 
0

Ciò è perché l'originale Un attività è già stata distrutta da tempo viene avviato da B, C o D. Pertanto, onCreate sarà chiamato al posto di onNewIntent(). Un modo per risolverlo è quello di distruggere sempre l'esistente A (quando si utilizza startActivity) prima di iniziare una nuova A, quindi onCreate verrà sempre chiamato, e tu metti il ​​codice di onNewIntent() in onCreate controllando se getIntent () è l'intento con cui hai iniziato.

Problemi correlati