基于https://www.wanandroid.com每日一问的笔记,做一些整理,方便自己进行查看和记忆。

原文链接:https://www.wanandroid.com/wenda/show/8697
以及nanchen的文章


  • 使用非 Activity 的 startActivity()的时候,都需要指定Intent.FLAG_ACTIVITY_NEW_TASK,如果没有指定,直接进行操作则会直接抛出异常
  • 使用 applicationContext 来做 startActivity() 操作,却没有指定任何的 FLAG,但是,在 8.0 的手机上,你一定会惊讶的发现,我们并没有等到意料内的崩溃日志,而且跳转也是非常正常,这不由得和我们印象中必须加 FLAG 的结论大相径庭。然后再拿一个 9.0 的手机来尝试,马上就出现了上面的崩溃

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    //SDK 26
    @Override
    public void startActivity(Intent intent, Bundle options) {
    warnIfCallingFromSystemProcess();
    // Calling start activity from outside an activity without FLAG_ACTIVITY_NEW_TASK is
    // generally not allowed, except if the caller specifies the task id the activity should
    // be launched in.
    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0
    && options != null && ActivityOptions.fromBundle(options).getLaunchTaskId() == -1) {
    throw new AndroidRuntimeException(
    "Calling startActivity() from outside of an Activity "
    + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
    + " Is this really what you want?");
    }
    mMainThread.getInstrumentation().execStartActivity(
    getOuterContext(), mMainThread.getApplicationThread(), null,
    (Activity) null, intent, -1, options);
    }
    //SDK 28
    @Override
    public void startActivity(Intent intent, Bundle options) {
    warnIfCallingFromSystemProcess();
    // Calling start activity from outside an activity without FLAG_ACTIVITY_NEW_TASK is
    // generally not allowed, except if the caller specifies the task id the activity should
    // be launched in. A bug was existed between N and O-MR1 which allowed this to work. We
    // maintain this for backwards compatibility.
    final int targetSdkVersion = getApplicationInfo().targetSdkVersion;
    if ((intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) == 0
    && (targetSdkVersion < Build.VERSION_CODES.N
    || targetSdkVersion >= Build.VERSION_CODES.P)
    && (options == null
    || ActivityOptions.fromBundle(options).getLaunchTaskId() == -1)) {
    throw new AndroidRuntimeException(
    "Calling startActivity() from outside of an Activity "
    + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
    + " Is this really what you want?");
    }
    mMainThread.getInstrumentation().execStartActivity(
    getOuterContext(), mMainThread.getApplicationThread(), null,
    (Activity) null, intent, -1, options);
    }
  • 使用 Context.startActivity() 的时候是一定要加上 FLAG_ACTIVITY_NEW_TASK 的,但是在 Android N 到 O-MR1,即 24~27 之间却出现了 bug,即使没有加也会正确跳转。

  • 非 Activity 调用 startActivity() 的时候,我们这个 options通常是 null 的,所以在 24~27 之间的时候,误把判断条件 options == null 写成了options != null 导致进不去 if,从而不会抛出异常。