Autore Topic: onActivityResult() non chiamato  (Letto 694 volte)

Offline elfo83

  • Utente normale
  • ***
  • Post: 287
  • Respect: +23
    • Mostra profilo
  • Sistema operativo:
    Mac OS 10.8.2
onActivityResult() non chiamato
« il: 29 Agosto 2013, 23:01:33 CEST »
0
Salve a tutti, proprio oggi mi sono reso conto di avere un problema: quando lancio la mia applicazione apro una attività di presentazione in cui l'utente può scegliere se fare il login con fb o tramite email. In questa attività c'è un'animazione che costa molto in termini di memoria, ma una volta che l'utente effettua il login, l'attività viene distrutta e conseguentemente libero tutte le risorse, comprese quelle utilizzate  dall'animazione. Fino a qui non ci sono problemi. Quando da questa prima attività clicco su un pulsante per fare il login con l'email, entro in una seconda attività nella quale posso inserire i miei dati e andare a fare il login vero e proprio. Dall'attività iniziale faccio partire quella di login con un startActivityForResult, perchè fino a quando non sono sicuro che l'utente abbia effettuato il login, non voglio distruggere la mia attività iniziale. Quindi... nella prima avrò:

Codice (Java): [Seleziona]
Intent intent = new Intent (getApplicationContext(), signIn.class);
                startActivityForResult(intent,LOGIN_SUCCESS);
               

e nell'attivity di login, nel caso in cui ho la risposta positiva dal server eseguo:
Codice (Java): [Seleziona]
 Intent intent = new Intent(this, MainActivity.class);
                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(intent);
                setResult(RESULT_OK);
                finish();      

Nella prima attività avrò il metodo onActivityResult in cui controllo se posso chiamare finish() o no:

Codice (Java): [Seleziona]
@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data)
    {
           
            super.onActivityResult(requestCode, resultCode, data);

               
       
        if(requestCode==LOGIN_SUCCESS)
        {
                if(resultCode==RESULT_CANCELED)
                        login_busyview.setVisibility(View.INVISIBLE);
                else
                {
                        Log.d("LOGIN SUCCESS ACTIVITY RESULT","OK");
                        finish();
                }
        }
}

Ho notato che non entro mai nel metodo onActivityResult() nel caso in cui effettuo il login. Invece, nel caso in cui torno indietro tramite il pulsante back dall'attività di login alla prima, entro nell'onActivityResult(). Ho letto diverse discussioni su diversi forum e tra le soluzioni ci sono quelle di non utilizzare l'attributo launchMode nel manifest per le attività coinvolte, non utilizzare l'attributo noHistory nel manifest, provare ad utilizzare il metodo HandleActivityResult() anzichè onActivityResult(). Insomma le ho provate tutte ma non va. Ho risolto invece settando nelle sharedPrefrences un valore che indica che ho effettuato il login e utilizzando un Thread nella prima attività,che controlla ogni mezzo secondo se nelle sharedPreferences quel valore esiste o no. Infine il thread chiama finish() quando trova il valore desiderato. Potrei lasciare tutto così ma mi rendo conto che sto creando e utilizzando del codice superfluo (che magari può in qualche modo compromettere l'applicazione) quando ho sempre fatto tutto ciò con onActivityResult(). Preferirei utilizzare quest'ultimo. Qualcuno può aiutarmi? Grazie

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:onActivityResult() non chiamato
« Risposta #1 il: 30 Agosto 2013, 08:04:28 CEST »
0
Se ho capito bene: tu hai una activity A in cui chiami la B aspettando un risultato, nella B se il login ha successo imposti setresult OK, a questo punto se vuoi tornare alla A basta un finish, ma se poi anche nella A chiami finish come avvi la C ?
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline GabMarioPower

  • Moderatore globale
  • Utente senior
  • *****
  • Post: 606
  • Respect: +153
    • Github
    • Google+
    • gabrielemariotti
    • GabMarioPower
    • Mostra profilo
  • Play Store ID:
    GAB+MARIO+DEV
  • Sistema operativo:
    Ubuntu 14.04 , Win 10
Re:onActivityResult() non chiamato
« Risposta #2 il: 30 Agosto 2013, 08:30:48 CEST »
0
Non l'ho mai provato ma se tu fai
Codice (Java): [Seleziona]
startActivity(intent);nella ActivityB, finisci in C e di conseguenza non torni in A, del resto non possono partire due Activity.

Potresti lanciare l'ActivityC nel onActivityResult della ActivityA.

O potresti semplificare le cose.
Perchè costringi l'utente a ben due screen per fare un login, per di più con una animazione pesante?
Ridisegna l'Activity A in modo da poter gestire sia il login con FB sia il login tramite email. Ci sono molti esempi di questo tipo.

E personalmente, se non funzionale allo scopo (e in un login faccio fatica a vederlo) eliminerei anche l'animazione.

Offline elfo83

  • Utente normale
  • ***
  • Post: 287
  • Respect: +23
    • Mostra profilo
  • Sistema operativo:
    Mac OS 10.8.2
Re:onActivityResult() non chiamato
« Risposta #3 il: 30 Agosto 2013, 16:30:45 CEST »
0
Innanzitutto grazie per le risposte. Provo a spiegarmi meglio:
Bradipao:

l'activity A avvia la B con startActivityForResult(..). Utilizzo startActivityForResult()  perché mi aspetto che una volta che l'attività B abbia la conferma che l'utente ha effettuato il login con successo, l'attività B, prima di terminare, setti setResult(RESULT_OK) in modo tale da andare nell'activity C e nello stesso tempo terminare la A. Una volta che ho il permesso di fare il login, non voglio tornare alla A, voglio solo andare alla C e terminare la A.

GabMarioPower:
prima che l'Activity B finisca e si passi alla C, nell'activity B chiamo setResult(RESULT_OK) proprio per dire alla A che il login è andato a buon fine e che deve terminare. Se invece lanciassi la C nell'onActivityResult() della A, l'utente non vedrebbe per un attimo che l'applicazione lo sta facendo tornare indietro all'attività A prima di fare il login?
Per quanto riguarda le altre osservazioni, sono pienamente d'accordo con te ma e specifiche sono queste e non posso fare di testa mia. Purtroppo quando a capo di un progetto ci sono persone incompetenti e senza esperienza succedono queste cose.

Come potrei risolvere senza modificare la logica delle Activity? Grazie

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:onActivityResult() non chiamato
« Risposta #4 il: 30 Agosto 2013, 16:39:39 CEST »
0
l'activity A avvia la B con startActivityForResult(..). Utilizzo startActivityForResult()  perché mi aspetto che una volta che l'attività B abbia la conferma che l'utente ha effettuato il login con successo, l'attività B, prima di terminare, setti setResult(RESULT_OK) in modo tale da andare nell'activity C e nello stesso tempo terminare la A. Una volta che ho il permesso di fare il login, non voglio tornare alla A, voglio solo andare alla C e terminare la A.

Come accennato da Gab, il modo per fare quello che ti serve è leggermente diverso.
- A aperta
- lanci B con startActivityForResult
- la B setta OK e chiama finish
- torni alla A dove viene eseguita la onActivityResult della A
- nella onActivityResult della A controlli il result, se è OK allora lanci la C e chiami finish della A

Citazione
Se invece lanciassi la C nell'onActivityResult() della A, l'utente non vedrebbe per un attimo che l'applicazione lo sta facendo tornare indietro all'attività A prima di fare il login?

Normalmente no. Il fatto è che se non vuoi tornare alla A, devi chiama direttamente la C dalla B.

PS: le activity "non girano in parallelo", per cui quando fai setResult non comunichi niente, metti semplicemente il flag OK nel messaggio che torna indietro dalla B alla A.
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline elfo83

  • Utente normale
  • ***
  • Post: 287
  • Respect: +23
    • Mostra profilo
  • Sistema operativo:
    Mac OS 10.8.2
Re:onActivityResult() non chiamato
« Risposta #5 il: 30 Agosto 2013, 16:45:19 CEST »
0
Ok, grazie allora provo a vedere se ho problemi nel lanciare l'activity C direttamente dalla A. Secondo quello che ho capito, nel momento in cui dalla A vado in B e poi dalla B starto la C, è come se vedessi in quel momento solo l'activity B e C. La A è in stop e quindi per terminarla posso solo che tornare indietro alla A e chiamare finish() da li giusto? Grazie.

Post unito: 30 Agosto 2013, 16:58:54 CEST
Perfetto, ho risolto chiamando l'Activity C direttamente dalla A e sembra che funziona tutto. Nel momento in cui entro nella C sia l'Activity A che l'ativity B vengono distrutte liberando le risorse. Qual'è il modo migliore per liberare le risorse di un'animazione oltre che usare unbindDrawables()?


Post unito: 30 Agosto 2013, 23:37:06 CEST
Ho notato che ho un'altro problema sempre nello stesso meccanismo. Cerco di essere chiaro:
activity A: presentazione, l'utente può scegliere se loggare con facebook o email. In quest'activity c'è un'animazione pesante.
activity B: login con email.
activity C: l'utente ha eseguito il login correttamente ed è la prima attività dell'applicazione vera e propria.

Nel momento in cui l'utente entra , chiamo il metodo finish() sia sull'attività A che B. In questo modo mi trovo aperta solo la C e rilascio le risorse utilizzate nella A e nella B. Quando cerco di entrare con facebook, dall'attività A apro il il facebook dialog e una volta che eseguo il login su fb e ottengo la sua risposta apro la mia attività B che deve verificare alcune cose (tipo se l'utente esiste già o se il device è già registrato ad un altro utente e così via). L'attività B la chiamo in questo modo:

Codice (Java): [Seleziona]
Params.printLog(TAG, "----FBLoggedIn---");
                Intent intent = new Intent(this, MainActivity.class);
                intent.putExtra("fbinfo", obj.toString());
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivityForResult(intent,LOGIN_FBSUCCESS);

Nel caso in cui ho un errore di login dell'applicazione con fb , ad esempio che il device è già registrato ad un altro utente, setto come risultato setResult(RESULT_CANCELED) e poi chiamo finish() sull'attività B. In questo modo tornerò all'attività A dove potrò scegliere nuovamente come loggarmi. Quello che ho notato è questo:
quando parte l'attività A il mio heap è 25mb. Quando eseguo il login con email (A-->B poi B ottiene la risposta positiva per il login, quindi finisce e setta RESULT_OK AD A ed infine A-->C e poi A termina ) noto che quando sono in C la mi heap va da 25mb a 15mb (presuppongo che ho rilasciato le mie risorse occupate da A e B). Invece quando da A voglio fare il login con fb, una volta che inserisco i dati corretti e vado in B, nel caso in il device è già registrato con un altro utente, da B vado in A e chiudo B. In teoria ho solo un'attività aperta: A e il mio heap è sempre 25mb. Se ora vado a fare il login con l'email, una volta che mi trovo in C e dopo aver terminato come sempre A e B, noto che la mia heap parte da 25mb senza scendere di 1k, come se le risorse non le rilasciasse. Come mai secondo voi?
« Ultima modifica: 30 Agosto 2013, 23:37:06 CEST da elfo83, Reason: Merged DoublePost »