2012-01-22 11 views
19

Quando si prova a startActivityForResult per Activity che dispone di launchMode="singleTask"; non restituirà alcun valore con onActivityResult e quando si imposta launchMode="standard"; tutto funziona bene, ma i requisiti di sistema dicono che questo Activity deve essere singleTask, c'è comunque da risolvere?onActivityResult con launchMode = "singleTask"?

risposta

39

La documentazione del startActivityForResult dicono:

For example, if the activity you are launching uses the singleTask launch mode, 
it will not run in your task and thus you will immediately receive a cancel result. 

Sembra che non v'è alcun modo per aggirare questo.

Se sei lo sviluppatore di Attività chiamata, puoi farlo inviare una trasmissione quando sono disponibili alcuni risultati. L'attività chiamante può quindi elencare queste trasmissioni.

+0

Quindi come impedire la creazione di più istanze di (ad esempio una lista) in onClick? – Imon

+7

Imon, utilizzare singleTop – joox

6

Cosa dice @Peter Knego

più

che sembra funzionare a 5.1, non in 4.4.4

senso che onActivityResult incendi

+0

Sì, ho anche osservato che funziona in 5.o e sopra non in 4.4.4 – Mahesh

33

La risposta mostra nella funzione di startActivityUncheckedLocked classe ActivityStackSupervisor. Prima di Android 5.x, all'avvio di un'attività, controlla prima launchMode e aggiunge FLAG_ACTIVITY_NEW_TASK all'avvio di Flags se launchMode è singleTask o singleInstance. Se launchFlags dell'attività contiene FLAG_ACTIVITY_NEW_TASK, invierà immediatamente un annullamento e lascerà che la nuova attività continui come di consueto senza una dipendenza dal suo mittente.

if (sourceRecord == null) { 
    // This activity is not being started from another... in this 
    // case we -always- start a new task. 
    if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { 
     Slog.w(TAG, "startActivity called from non-Activity context; forcing " + 
       "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent); 
     launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 
    } 
} else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 
    // The original activity who is starting us is running as a single 
    // instance... this new activity it is starting must go on its 
    // own task. 
    launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 
} else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE 
     || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { 
    // The activity being started is a single instance... it always 
    // gets launched into its own task. 
    launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 
} 
// ...... 
if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 
    // For whatever reason this activity is being launched into a new 
    // task... yet the caller has requested a result back. Well, that 
    // is pretty messed up, so instead immediately send back a cancel 
    // and let the new task continue launched as normal without a 
    // dependency on its originator. 
    Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result."); 
    r.resultTo.task.stack.sendActivityResultLocked(-1, 
      r.resultTo, r.resultWho, r.requestCode, 
     Activity.RESULT_CANCELED, null); 
    r.resultTo = null; 
} 

Ma in 5.x Android, questo è stato cambiato come di seguito:

final boolean launchSingleTop = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP; 
final boolean launchSingleInstance = r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE; 
final boolean launchSingleTask = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK; 
int launchFlags = intent.getFlags(); 
if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && 
     (launchSingleInstance || launchSingleTask)) { 
    // We have a conflict between the Intent and the Activity manifest, manifest wins. 
    Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " + 
      "\"singleInstance\" or \"singleTask\""); 
    launchFlags &= 
      ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); 
} else { 
    switch (r.info.documentLaunchMode) { 
     case ActivityInfo.DOCUMENT_LAUNCH_NONE: 
      break; 
     case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING: 
      launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 
      break; 
     case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS: 
      launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 
      break; 
     case ActivityInfo.DOCUMENT_LAUNCH_NEVER: 
      launchFlags &= ~Intent.FLAG_ACTIVITY_MULTIPLE_TASK; 
      break; 
    } 
} 
final boolean launchTaskBehind = r.mLaunchTaskBehind 
     && !launchSingleTask && !launchSingleInstance 
     && (launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0; 
if (r.resultTo != null && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 
    // For whatever reason this activity is being launched into a new 
    // task... yet the caller has requested a result back. Well, that 
    // is pretty messed up, so instead immediately send back a cancel 
    // and let the new task continue launched as normal without a 
    // dependency on its originator. 
    Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result."); 
    r.resultTo.task.stack.sendActivityResultLocked(-1, 
      r.resultTo, r.resultWho, r.requestCode, 
      Activity.RESULT_CANCELED, null); 
    r.resultTo = null; 
} 

Ecco perché onActivityResult opere in Android 5.x anche si imposta launchMode a singleTask o singleInstance.

-1

So che questo è abbastanza tardi ma è possibile avere OnActivityResult tipo di effetto sul metodo onNewIntent() perché questa è l'attività singleTask.

Problemi correlati