基类 Context 的 Activity 组件启动方法,startActivity() 是个抽象方法。
public abstract void startActivity(@RequiresPermission Intent intent);
子类 ContextWrapper 的具体实现,交给装饰 mBase,即 ContextImpl 完成。
@Override
public void startActivity(Intent intent) {
mBase.startActivity(intent);
}
Activity 继承 ContextWrapper,重写该方法,委托 Instrumentation 对象,执行 IActivityTaskManager 的 startActivity() 方法。
ActivityTaskManager.getService().startActivity()
若不重写,如 Service,也是 ContextWrapper 的子类,将执行 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);
}
在服务中启动 Activity 组件,如果不添加这个 FLAG_ACTIVITY_NEW_TASK 这个标志,很容易出现 “Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag.” 的错误。
同样,在广播 BroadcastReceiver 中启动 Activity 组件,入参的 Context 也需要这个标志。
任重而道远