android4.0+已经占据目前主流android系统版本了,在5.0版本发布后,android的LaunchMode与StartActivityForResult的关系发生了一些改变。

两个Activity,A和B,现在由A页面跳转到B页面,看一下LaunchMode与StartActivityForResult之间的关系:

android5.0之前

stand singleTop singleTask singleInstance
stand x x
singleTop x x
singleTask x x
singleInstance x x x x

android5.0之后

stand singleTop singleTask singleInstance
stand
singleTop
singleTask
singleInstance

为什么会是这样的呢?

ActivityStackSupervisor类中的startActivityUncheckedLocked方法在5.0中进行了修改。在5.0之前,当启动一个Activity时,系统将首先检查Activity的launchMode,如果为A页面设置为SingleInstance或者B页面设置为singleTask或者singleInstance,则会在LaunchFlags中加入FLAG_ACTIVITY_NEW_TASK标志,而如果含有FLAG_ACTIVITY_NEW_TASK标志的话,onActivityResult将会立即接收到一个cancle的信息。

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

在5.0(含)之后的系统中,对此方法进行了修改:

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

这就解析了为什么5.0(含)之后的系统即便启动的页面设置launchModesingleTasksingleInstanceonActivityResult依旧可以正常工作。

更多文章请访问小胖轩.

更多相关文章

  1. android 7.0 系统关闭彩信过CTA测试的方法
  2. Android(安卓)SDK 安装过程及安装失败的处理方法[转]
  3. android Setting中隐藏项
  4. 让Android(安卓)变身回一台真正的Linux系统吧!!!
  5. Android(安卓)文件系统及权限修改
  6. android 小知识
  7. Android接入WebView(五)——浏览器制作总结及源码分享
  8. Android(安卓)文件系统及权限修改
  9. 修改android 睡眠的时间的两种方法

随机推荐

  1. Android捕获Home键
  2. Android中的category大全
  3. Android使用selector改变文字的颜色
  4. android第三天--AbsoluteLayout绝对布局
  5. Android(安卓)xposed Hook 初探01
  6. android webview 添加内置对象
  7. Error string types not allowed at andr
  8. Android(安卓)获取AndroidManifest.xml
  9. How to install Android(安卓)SDK in Ubu
  10. android中ProgressBar的使用SeekBar的使