2012-01-22 52 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活動。

相關問題