Utilizzando startActivityForResult, come ottenere requestCode nell'attività figlio?


88

Ho quattro attività, diciamo A, B, C e D. La mia situazione è A inizierà l'attività B da startActivityForResult.

startActivityForResult(new Intent(this,B.class),ONE);

In altre situazioni mi B con altre situazioni. piace

 startActivityForResult(new Intent(this,B.class),TWO);

In B, devo chiamare C o D a seconda della richiestaCodice. Ad esempio, se UNO ha bisogno di avviare C, altrimenti D.
Quindi ho bisogno di sapere come controllare il requestCode nell'attività figlio (B qui).
In altre parole, desidero ottenere il codice di richiesta con cui è stata avviata l'attività B.

Risposte:


140

Puoi passare il codice di richiesta inserendo extra.

intent.putExtra("requestCode", requestCode);   

Oppure, se avete usato startActivityForResultmolte volte, quindi meglio di editing ciascuno, è possibile overridel' startActivityForResultnel vostro Activity, è aggiungere il codice lì come questo

@Override
    public void startActivityForResult(Intent intent, int requestCode) {
        intent.putExtra("requestCode", requestCode);
        super.startActivityForResult(intent, requestCode);
    }

Quindi non è necessario modificare tutto il tuo startActivityForResult
Spero che ti abbia aiutato


51
Non c'è davvero alcun modo per un'attività figlio di ottenere il suo codice di richiesta?
i_am_jorf

1
Fino ad ora per la mia migliore Conoscenza, non penso in altro modo.
Labeeb Panampullan

17
Mi chiedevo la stessa cosa: questa è una di quelle cose nelle API Android che non ha alcun senso logico.
Artem Russakovskii

9
startActivityForResult può essere utilizzato per avviare attività in altre app, requestCode è l'argomento privato della tua app. In questa luce ha senso che l'Intent non abbia un tale metodo e l'approccio giusto è impostare l'Azione consigliando esattamente cosa vuoi che faccia l'attività.
Maciej Beimcik

28

Il codice della richiesta non viene passato automaticamente all'attività avviata perché non è necessario (e non dovrebbe) conoscere questo valore. Ha solo bisogno di sapere cosa fare e non da dove è stato avviato.

Avviare un'attività è in realtà solo un'altra forma di chiamare un metodo. Quando chiami un metodo, ricevi il risultato in modo sincrono (proprio lì dove hai effettuato la chiamata). In questo caso stai solo trasmettendo le informazioni di cui il metodo ha bisogno per fare il suo lavoro. Non gli stai dicendo da dove l'hai chiamato.

L'avvio di un'attività è l'analogo asincrono della chiamata di un metodo, nel qual caso si riceve il risultato nel metodo speciale onActivityResult (). In questo metodo, devi sapere cosa fare con il risultato che hai appena ricevuto e hai il codice di richiesta per questo.

Per rendere un po 'più chiaro il motivo per cui non è una buona idea passare il codice della richiesta come parametro, considera l'attività di esempio che mostra un prodotto che puoi acquistare. In questa attività ci sono due pulsanti etichettati "Acquista" e "Accedi" (poiché attualmente non sei loggato). Premendo "Login" inizierà un'attività denominata "Login" che tenterà di accedere all'utente utilizzando le informazioni fornite. Premendo "Acquista" inizierà prima la stessa attività di "Login" e se il login è andato a buon fine, inizierà l'attività di acquisto.

Ora, il pulsante "Accedi" utilizza il codice di richiesta 1 per avviare l'attività di accesso, ma il pulsante "Acquista" non può utilizzare lo stesso codice di richiesta in quanto dovrà fare qualcosa di diverso se il login ha successo. Quindi, il pulsante "Acquista" utilizza il codice di richiesta 2.

Nell'attività "Login" potresti ricevere due diversi codici di richiesta a seconda di dove è stato chiamato, ma dovrai eseguire la stessa procedura.

Quindi, se passi il codice della richiesta come parametro, ti ritroverai con il codice che deve fare le stesse cose per un paio di codici di richiesta diversi, come:

if (requestCode == LOGIN || requestCode == BUY) {
    // ...
} else ...

Finirai anche per memorizzare le costanti del codice di richiesta in una posizione centrale, ad esempio una classe chiamata RequestCodes.

In breve, il codice di richiesta dovrebbe essere utilizzato solo per decidere cosa fare con il risultato ricevuto. In questo modo ti ritroverai con un codice più modulare, più facile da mantenere e più facile da estendere.


1
E se si tratta di un "gestore" di sorta e si desidera che un codice di richiesta arrivi per "salvare" un determinato valore (valore salvato in extra). Un altro codice di richiesta che "recupererebbe" un valore (e restituirebbe in extra) ma all'interno di questa attività possono anche gestire complessivamente i valori salvati come rinominare, modificare, cancellare, ecc. Cosa ne pensi di qualcosa del genere? Penso che impedirebbe la duplicazione di codice / attività per eseguire le stesse azioni.
JRomero

@ J.Romero Non farlo, complicherà solo le cose. Metti semplicemente quella funzionalità in una classe (utility / singleton). Potresti anche dare un'occhiata a Handler and Service
Szabolcs Berecz

3
Szabolcs L'attività del bambino, anche se "non ha bisogno di conoscere questo valore", potrebbe dover trasferire il valore all'attività successiva di una catena. Ironia della sorte, abbiamo bisogno di scrivere codice più ridondante per questo. Per qualcosa che non abbiamo bisogno di sapere tanto quanto riceviamo più lezioni da leggere su ciò che non dovremmo fare.
user250343

Non vedo come questo illustri il motivo per cui a un'attività figlio dovrebbe essere negato l'accesso al codice di richiesta. Non sono nemmeno sicuro del motivo per cui l'accesso al codice di richiesta sarebbe necessario nel tuo esempio particolare considerando che l'acquisto ora e le chiamate di accesso sono comunque due attività separate.
Drazen Bjelovuk

1
@EvanR. forse un'architettura migliore sarebbe quella di sottoclassare l'attività dell'elemento "principale" in attività di aggiunta / modifica separate. Quindi c'è un riutilizzo minimo del codice, ma ogni attività può essere richiamata indipendentemente.
Dane Powell

11

Ho finito per utilizzare un'azione Intent personalizzata per passare questo tipo di informazioni all'attività di lancio.

protected static final String ACTION_DO_C = "do_c";
protected static final String ACTION_DO_D = "do_d";

Allora andresti come:

final Intent intent = new Intent(this,B.class)
intent.setAction(ACTION_DO_C);
startActivityForResult(intent,ONE);

E in Attività Bottieni facilmente l'azione:

getIntent().getAction();

funziona come un fascino, la migliore risposta davvero. Grazie.
YvesLeBorg

0

È possibile utilizzare getCallingActivity () per ottenere l'attività che ha avviato l'attività corrente e che riceverà il valore del risultato con il codice di risposta alla fine.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.