2012-01-22 10 views
19

Cuando intenta startActivityForResult para Activity que tiene launchMode="singleTask"; no devolverá ningún valor con onActivityResult, y cuando configure launchMode="standard"; todo funciona bien, pero los requisitos del sistema dicen que este Activity debe ser singleTask, ¿hay alguna forma de solucionar esto?onActivityResult con launchMode = "singleTask"?

Respuesta

39

Los documentos de la startActivityForResult dicen:

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. 

Parece que no hay manera de evitar esto.

Si usted es el desarrollador de la actividad llamada, puede hacer que envíe una transmisión cuando haya algún resultado disponible. La actividad de llamada puede entonces listarse a estas transmisiones.

+0

Entonces, ¿cómo evitar la creación de múltiples instancias de (por ejemplo, una vista de lista) en onClick? – Imon

+7

Imon, use singleTop – joox

6

Qué dice @Peter Knego

más

parece estar funcionando en 5.1, 4.4.4 no en

significado que onActivityResult incendios

+0

Sí, también observé que funciona en 5.o y arriba, no en 4.4.4 – Mahesh

33

La respuesta muestra en función de startActivityUncheckedLocked clase ActivityStackSupervisor. Antes de Android 5.x, cuando se inicia una actividad, primero se verifica launchMode y se agrega FLAG_ACTIVITY_NEW_TASK para lanzarFlags si launchMode es singleTask o singleInstance. Si el launchFlags de la actividad contiene FLAG_ACTIVITY_NEW_TASK, devolverá una cancelación inmediatamente y permitirá que la nueva tarea continúe iniciada normalmente sin una dependencia en su creador.

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; 
} 

Pero en 5.x Android, esto fue cambiado de la siguiente manera:

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; 
} 

Por eso onActivityResult obras en 5.x Android incluso que establecen launchMode a singleTask o singleInstance.

-1

Sé que esto es bastante tarde pero puede tener el tipo de efecto OnActivityResult en el método onNewIntent() porque esta es su actividad singleTask.

Cuestiones relacionadas