基類 Context 的 Activity 組件啟動方法谢床,startActivity() 是個抽象方法兄一。
public abstract void startActivity(@RequiresPermission Intent intent);
子類 ContextWrapper 的具體實現(xiàn)识腿,交給裝飾 mBase,即 ContextImpl 完成骂束。
@Override
public void startActivity(Intent intent) {
mBase.startActivity(intent);
}
Activity 繼承 ContextWrapper硝全,重寫該方法,委托 Instrumentation 對象伟众,執(zhí)行 IActivityTaskManager 的 startActivity() 方法。
ActivityTaskManager.getService().startActivity()
若不重寫账胧,如 Service纳令,也是 ContextWrapper 的子類慢叨,將執(zhí)行 ContextImpl 類的 startActivity() 方法啰扛。
@Override
public void startActivity(Intent intent, Bundle options) {
warnIfCallingFromSystemProcess();
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);
}
在服務(wù)中啟動 Activity 組件管行,如果不添加這個 FLAG_ACTIVITY_NEW_TASK 這個標志准脂,很容易出現(xiàn) “Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag.” 的錯誤檬洞。
同樣,在廣播 BroadcastReceiver 中啟動 Activity 組件湾戳,入?yún)⒌?Context 也需要這個標志。
任重而道遠