2012-01-22 33 views
19

Khi bạn cố gắng startActivityForResult cho ActivitylaunchMode="singleTask"; nó sẽ không trả lại bất kỳ giá trị nào với onActivityResult và khi bạn đặt launchMode="standard"; tất cả mọi thứ hoạt động tốt, nhưng yêu cầu hệ thống nói rằng Activity này phải là singleTask, có cách nào để giải quyết vấn đề này không?onActivityResult Với ​​launchMode = "singleTask"?

Trả lời

39

Các tài liệu của startActivityForResult nói:

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. 

Có vẻ như không có cách nào để làm được việc này.

Nếu bạn là nhà phát triển của Hoạt động được gọi, sau đó bạn có thể yêu cầu phát sóng khi có một số kết quả. Hoạt động gọi điện sau đó có thể liệt kê các chương trình phát sóng này.

+0

Vậy làm cách nào để ngăn việc tạo nhiều phiên bản (ví dụ: listview) trong onClick? – Imon

+7

Imon, sử dụng singleTop – joox

6

gì @ Peter Knego nói

cộng

có vẻ như được làm việc trong 5.1, không phải trong 4.4.4

nghĩa rằng onActivityResult cháy

+0

Có Tôi cũng quan sát thấy nó hoạt động trong 5.o và cao hơn không trong 4.4.4 – Mahesh

33

Câu trả lời cho thấy chức năng của startActivityUncheckedLocked lớp ActivityStackSupervisor. Trước khi Android 5.x, khi bắt đầu một hoạt động, nó sẽ kiểm tra launchMode đầu tiên và thêm FLAG_ACTIVITY_NEW_TASK để launchFlags nếu launchMode là singleTask hoặc singleInstance. Nếu launchFlags của hoạt động chứa FLAG_ACTIVITY_NEW_TASK, nó sẽ gửi lại hủy ngay lập tức và cho phép tác vụ mới tiếp tục khởi chạy như bình thường mà không phụ thuộc vào người khởi tạo của nó.

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

Nhưng trong 5.x Android, điều này đã được thay đổi như sau:

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

Đó là lý do onActivityResult công trình trong Android 5.x thậm chí bạn thiết launchMode để singleTask hoặc singleInstance.

-1

Tôi biết điều này khá muộn nhưng bạn có thể có OnActivityResult loại hiệu ứng trên phương thức onNewIntent() vì đây là hoạt động singleTask của bạn.

Các vấn đề liên quan