Autore Topic: Problema "pulizia" dello stack  (Letto 571 volte)

Offline crc_error

  • Utente junior
  • **
  • Post: 85
  • Respect: +8
    • Mostra profilo
  • Dispositivo Android:
    LG-P500
  • Sistema operativo:
    Windows 8, Ubuntu 12
Problema "pulizia" dello stack
« il: 07 Ottobre 2013, 18:23:05 CEST »
0
Ciao a tutti,
ho un problema con lo stack della mia applicazione..

Ecco come dovrebbe funzionare: l'activity principale fa un controllo se l'utente è loggato. Se non lo è, chiude l'activity di ingresso (Home) e apre quella Login. L'utente si autentica e ritorna sulla Home (che ripete il controllo e questa volta visualizza il contenuto).

Fin qui tutto ok. Il back stack funziona correttamente: la login è raggiungibile solo se non si è loggati e il tasto back sia qui, che nella home riporta al launcher.

Il problema nasce quando dalla Home (loggato) mi sposto ad un'altra activity (p.e. la About).
Se dalla About clicco logout, il processo di logout funziona correttamente e vengo indirizzato alla Login. Ora però se nella login premo il tasto back, ritorno alla Home (come se fossi loggato)... In pratica è come se le mie FLAG_* allo start dell'activity vengano ignorate

- Launcher ->
 1 Home | non loggato ->
 2 Login ->
 3 Home | loggato ->
 4 About | eseguo il logout ->
 5 Login

 -  tasto back ritorna alla 3

Questo è il mio AndroidManifest.xml

Codice (XML): [Seleziona]
....
        <activity
           android:name=".activities.Act_Home"
           android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity
           android:name=".activities.Act_Login"
           android:clearTaskOnLaunch="true"
           android:noHistory="true"
           android:excludeFromRecents="true"
           android:label="@string/titleLogin" />

        <activity
           android:name=".activities.Act_About"
           android:label="@string/titleAbout"
           android:parentActivityName="com.sample.app.activities.Act_Home">
            <meta-data
               android:name="android.support.PARENT_ACTIVITY"
               android:value="com.sample.app..activities.Act_Home"/>
        </activity>

...

Questo invece è lo start activity presente nei click sui pulsanti Logout:

Codice (Java): [Seleziona]
    //
    // eseguito il logout pulisco task e stack, ne creo uno nuovo e vado alla activity di login.
    //
    public void toLogin() {
        Intent intent = new Intent(this, Act_Login.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
        finish();
    }

Questo invece è lo startActivity() che dalla Login manda alla HOME una volta che l'utente si è autenticato.
Anche qua pulisco nuovamente task e stack, ne creo di nuovi e lancio l'activity.

Codice (Java): [Seleziona]
            Intent intent = new Intent(context, Act_Home.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
            intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.putExtra(getPackageName()+"."+AppDbHelper.TBUSER_ID, userId);
            context.startActivity(intent);
            finish();

Dopo vari tentativi ho trovato questa pagina: http://stackoverflow.com/questions/5979171/clear-all-activities-in-a-task dove un'altro utente ha un problema simile al mio.
Ho provato con la soluzione suggerita ma con me non funziona :(

Grazie mille in anticipo.




Offline Melanogaster

  • Utente normale
  • ***
  • Post: 260
  • Respect: +11
    • Mostra profilo
  • Dispositivo Android:
    SII
  • Sistema operativo:
    Kubuntu
Re:Problema &quot;pulizia&quot; dello stack
« Risposta #1 il: 08 Ottobre 2013, 00:30:47 CEST »
0
Se ho capito il tuo problema, non fai prima a mettere in ogni Activity 'protetta' un controllo per capire se si é loggati o no?
Io facevo così:
Codice: [Seleziona]
If (autenticato==false) {
Mostro un dialog di login che una volta loggato ricaricherà questa activity
}
Else {
setContentView(...);
}

Offline zorcraft

  • Utente junior
  • **
  • Post: 108
  • Respect: +5
    • Mostra profilo
  • Dispositivo Android:
    note
  • Play Store ID:
    zorcraft
Re:Problema "pulizia" dello stack
« Risposta #2 il: 08 Ottobre 2013, 09:12:30 CEST »
0
dove inserisci il codice con i vari intent?
in un evento di un bottone?
se la risposta e questa allora il tuo problema e che devi intercettare onKeyDown(int, KeyEvent) e eseguire il codice che fai eseguire al bottone anche quando viene premuto il tasto back

Offline crc_error

  • Utente junior
  • **
  • Post: 85
  • Respect: +8
    • Mostra profilo
  • Dispositivo Android:
    LG-P500
  • Sistema operativo:
    Windows 8, Ubuntu 12
Re:Problema &quot;pulizia&quot; dello stack
« Risposta #3 il: 08 Ottobre 2013, 11:56:02 CEST »
0
Se ho capito il tuo problema, non fai prima a mettere in ogni Activity 'protetta' un controllo per capire se si é loggati o no?
Io facevo così:
Codice: [Seleziona]
If (autenticato==false) {
Mostro un dialog di login che una volta loggato ricaricherà questa activity
}
Else {
setContentView(...);
}

Il controllo ce l'ho già.. in tutte le activities nell'onCreate, ho messo questo:

Codice (Java): [Seleziona]
        if(!checkLoginStatus()) // se il controllo fallisce vai alla login
            toLogin();

Perchè poi nello "onStart" e nel "onResume" ho tutti i metodi di disegno delle views e dell'app..

Il problema è nel logout dalle sub-activities.
Per qualche ragione lo stack o i task non vengono puliti e quindi mi ritrovo nel back le activities aperte prima di fare il logout.
In pratica vengono riesumate dal back (onStart() -> onResume) e non ricreate (onCreate() -> onStart() -> onResume). Per qualche ragione che mi sfugge le activities in coda nei task e nello stack non vengono distrutte quando passo alla "LOGIN".

1______2______3_______4         
Login - > Home -> About -> Login

Nel passaggio da 3 a 4 nell'intent pulisco lo stack, il task e ne creo uno nuovo, quindi lancio l'activity 4.
La stessa cosa succederà nell'activity 1-4 quando farò click sul bottone "LOGIN" (questa parte funziona però..)

Come riportato sopra il codice per la pulizia e il lancio dell'activity LOGIN è questo:
Codice (Java): [Seleziona]
    public void toLogin() {
        Intent intent = new Intent(this, Act_Login.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
        finish();
    }

Questo è da LOGIN a HOME:

Codice (Java): [Seleziona]
    private class ValidateUser extends AsyncTask<Void, Void, Long> {

        ...

        @Override
        protected void onPostExecute(Long userId) {
            if(userId == null || userId == 0)
                return;

            // Se tutto va bene ritorno alla home e gli passo l'id.
            Intent intent = new Intent(context, Act_Home.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
            intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.putExtra(getPackageName()+"."+AppDbHelper.TBUSER_ID, userId);
            context.startActivity(intent);
            finish();
        }

    }



@zorcraft: In pratica da 3 il codice per passare da 3 a 4 è in un optionsMenu

Codice (Java): [Seleziona]
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle item selection
        switch (item.getItemId()) {

            case R.id.optGlobalSettings:
                if (Build.VERSION.SDK_INT< Build.VERSION_CODES.HONEYCOMB)
                    startActivity(new Intent(contesto, Preferenze.class));
                else
                    startActivity(new Intent(contesto, Preferenze_JB.class));
                return true;

            case R.id.optGlobalLogOut:
                boolean stato = false;
                // per ora faccio così poi ritornerò un boolean e l'if(stato) lo butto nel onPostExecute dell'asynctask...
                try {
                    stato = utility.new UserLogOut(resolver).execute().get();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }
                if(stato)
                    toLogin();
                return true;

            case android.R.id.home:
                NavUtils.navigateUpFromSameTask(this);
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }