基于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 的手机来尝试,马上就出现了上面的崩溃
//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,从而不会抛出异常。