2015-08-06 12 views
6

Ho un'applicazione, che inizia con un SplashScreenActivity. Successivamente, viene mostrato un LoginActivity oppure, se l'utente ha già effettuato l'accesso, viene mostrato un numero MainActivity. Se l'applicazione è già in esecuzione, SplashScreenActivity è respinto con la seguenteAndroid: BackStack si comporta male, se l'applicazione è stata avviata da un'altra app

//SplashScreenActivity 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    //Adding this check for following cases 
    if (!isTaskRoot()) 
    { 
     String intentAction = getIntent().getAction(); 
     if (getIntent().hasCategory(Intent.CATEGORY_LAUNCHER) && intentAction != null && intentAction.equals(Intent.ACTION_MAIN)) { 
      finish(); 
      return; 
     } 

     if(getIntent().getCategories().contains(GCMIntentService.INTENT_CATEGORY_GH_NOTIFICATION)){ 
      finish(); 
      return; 
     } 
    } 

problema si verifica

Se inizio l'applicazione da un'altra attività, come PlayStore, si riprende l'attività giusta se già in esecuzione. Questo è il Intent che sto usando per riprodurre all'interno di una seconda applicazione

//AnotherApplication.apk 
Intent launchIntent = getPackageManager().getLaunchIntentForPackage("my.package.name"); 
startActivity(launchIntent); 

Tuttavia, questa azione è in qualche modo rompendo il Backstack. Invece di chiudere l'applicazione su backpress nel MainActivity, riavvia l'applicazione.

//MainActivity.class 
@Override 
public void onBackPressed() { 
    if (getNavDrawerMain().isDrawerOpen()) { 
     getNavDrawerMain().closeDrawer(); 
    } else { 
     closeApp(); 
    } 
} 

protected void closeApp() { 
    if (doubleBackToExitPressedOnce) { 
     //super.onBackPressed(); //i tried both, but behaviour is the same 
     finish(); 
     return; 
    } 
    this.doubleBackToExitPressedOnce = true; 

    new Handler().postDelayed(new Runnable() { 

     @Override 
     public void run() 
      doubleBackToExitPressedOnce = false; 
     } 
    }, 500); 
} 

Ho usato i punti di interruzione e ho scoperto che MainActivity: OnDestroy() vengono chiamati, ma invece di riprendere applicazione alla HomeScreen, si riavvia sempre e io non so perché.

Ho provato il seguente: - Utilizzato diverse modalità di avvio come singleTask e singleInstance, ma non ha fatto alcuna differenza. onNewIntent si chiama, ma se chiamo finish, HomeActivity riavvia - come commeted di seguito, ho provato moveTaskToBack(true), ma l'attività è restaring troppo (e abbiamo davvero voglia di chiudere l'applicazione, invece di spostarlo al BackStack)

+1

Nella mia esperienza, 'getLaunchIntentForPackage (...)' * non * restituisce un intento di avvio. Un intento di avvio solleverà l'attività esistente, ma gli intenti restituiti da 'getLaunchIntentForPackage (...)' ne avviano effettivamente uno nuovo. La tua app potrebbe non riavviarsi quando tornerai indietro; potresti semplicemente vederne un'altra copia. –

+1

@KevinKrumwiede: Intent ha il seguente tipo 'android.intent.action.MAIN', ho appena aggiunto del codice aggiuntivo, come gestisco l'intento – longilong

+1

Non riesco a trovare nulla che lo dica esplicitamente, ma sospetto che solo il sistema sia autorizzato a ricevere "ACTION_MAIN". –

risposta

1

Cercando l'aggiunta di questo flag per la vostra intenzione di iniziare la vostra applicazione: RESET_TASK_IF_NEEDED, URL = http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_RESET_TASK_IF_NEEDED

Cosa fa:

Se impostato, e questa attività è o viene avviato in una nuova attività o portare verso l'alto un'attività esistente, quindi sarà lanciato come porta d'ingresso del compito.

Si può anche utilizzare: http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_REORDER_TO_FRONT

Cosa fa:

Se occupa un Intent passato a Context.startActivity(), questo flag farà sì che l'attività avviata di essere portato verso la parte anteriore lo storico della sua attività se è già in esecuzione.

Quale si utilizza dipende dal risultato finale desiderato.

Se non è possibile controllare chi inizia, è necessario impostare o avviare la modalità su singola attività o singola istanza.

qui descritto:

http://inthecheesefactory.com/blog/understand-android-activity-launchmode/en

La parte interessante:

singleTask

Questa modalità è molto diversa dallo standard e singleTop.Un'attività con singleTask launchMode può avere solo un'istanza nel sistema (a.k.a Singleton). Se esiste un'istanza di attività esistente nel sistema, l'intera operazione di attesa dell'istanza verrà spostata in alto mentre Intent verrà recapitata tramite il metodo onNewIntent(). Altrimenti, la nuova attività verrebbe creata e inserita nell'appropriata attività.

+0

il problema è che l''Intento' da cui dovrei aggiungere i flag viene avviato da (nel nostro caso) 'Google Play Store' o' HockeyApp', quindi non possiamo cambiarli. O ho frainteso la tua domanda? – longilong

+0

Oh, quindi ti serve solo una singola istanza, una risposta aggiornata. – JohanShogun

+0

"... ha provato diversi launchmodes, ma non ha fatto alcuna differenza ..." forse avrei dovuto chiarire questo punto. Ho provato 'singleTop',' singleTask' ecc ... Non fa alcuna differenza. Vedo, quell'Attività viene distrutta, ma invece di tornare allo stack precedente, chiama 'onCreate()' di nuovo – longilong

1

Provare con moveTaskToBack(true); anziché finish(); per chiudere l'app. Andrà quindi a OnRestart() e quindi OnStart() -> OnResume() (e non andrà a OnCreate).

E assicurati di non avere il "Non mantenere attività" contrassegnato in Opzioni sviluppatore nelle impostazioni di Android (distruggere tutte le attività non appena l'utente lascia).

+1

grazie per il commento, ho appena provato ma il comportamento rimane lo stesso ... – longilong

+0

Assicurati di non avere il "Non mantenere attività" contrassegnato in Opzioni sviluppatore nelle impostazioni di Android (distruggere tutte le attività non appena l'utente lascia). –

Problemi correlati