基於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,從而不會拋出異常。