2012-01-22 111 views
19

当您尝试startActivityForResult对于Activity已具有launchMode="singleTask";它不会使用onActivityResult返回任何值,并且当您设置launchMode="standard"时;一切工作正常,但系统要求说这Activity必须是singleTask,有无论如何解决这个?onActivityResult with launchMode =“singleTask”?

回答

39

startActivityForResult的文档说:

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. 

看来是没有办法来解决这个问题。

如果您是所谓的Activity的开发者,那么当某些结果可用时,您可以让它发送广播。调用活动可以列表到这个广播。

+0

那么如何防止在onClick中创建多个实例(例如listview)呢? – Imon

+7

Imon,使用singleTop – joox

6

什么@Peter Knego说

似乎在5.1是工作,而不是在4.4.4

是onActivityResult火灾

+0

是的,我也观察到它在5.o及以上版本中的工作,而不是在4.4.4 – Mahesh

33

答案显示的功能startActivityUncheckedLocked意义类ActivityStackSupervisor。 在Android 5.x之前,在启动活动时,如果launchMode是singleTask或singleInstance,它将首先检查launchMode并添加FLAG_ACTIVITY_NEW_TASK以启动Flags。如果活动的launchFlags包含FLAG_ACTIVITY_NEW_TASK,它将立即发回取消,并让新任务继续正常继续启动,而不依赖其始发者。

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

但在Android的5.x中,这被更改如下:

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

这就是为什么onActivityResult作品的Android 5.x的,甚至你设置launchMode到singleTasksingleInstance

-1

我知道这已经很晚了,但是您可以在onNewIntent()方法上使用OnActivityResult类型的效果,因为这是您的singleTask活动。

相关问题