Activity的startActivity和Context的startActivity都可以启动一个Activity,它们的区别如下:
Activity的startActivity方法:
这种方式是在Activity内部调用startActivity方法,使用的上下文对象是当前的Activity对象。这种方式会自动将当前Activity作为启动Activity的上下文,并且会将新启动的Activity添加到当前Activity所在的任务栈中。
Context的startActivity方法:
context.startActivity(intent);
这种方式是在任何地方调用startActivity方法,使用的上下文对象是一个Context对象。这种方式可以在任何地方启动Activity,不仅限于Activity内部。但是需要注意的是,如果上下文对象不是一个Activity对象,即非Activity环境启动Activity时,需要加上Intent.FLAG_ACTIVITY_NEW_TASK标志位,以创建一个新的任务栈。
Activity的startActivity方法是在Activity内部调用,使用当前Activity作为上下文对象,会将新启动的Activity添加到当前Activity所在的任务栈中。
Context的startActivity方法可以在任何地方调用,使用任意一个Context对象作为上下文对象,需要注意非Activity环境启动Activity时需要加上Intent.FLAG_ACTIVITY_NEW_TASK标志位。
Context的startActivity代码如下:
//frameworks/base/core/java/android/content/Context.java
public abstract class Context {
public abstract void startActivity(@RequiresPermission Intent intent);
}
Context是抽象类,由其子类ContextImpl实现:
//frameworks/base/core/java/android/content/ContextImpl.java
class ContextImpl extends Context {
public void startActivity(Intent intent) {
warnIfCallingFromSystemProcess();
startActivity(intent, null);
}
}
调用重载方法:
//frameworks/base/core/java/android/content/ContextImpl.java
class ContextImpl extends Context {
final @NonNull ActivityThread mMainThread;
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);
}
}
上述方法主要处理如下:
1、调用mMainThread(ActivityThread)的getInstrumentation方法,取得Instrumentation。
2、调用ContextImpl的getOuterContext方法,取得外部Context。
3、调用mMainThread(ActivityThread)的getApplicationThread方法,取得ApplicationThread。
4、调用Instrumentation的execStartActivity方法,执行应用程序发出的 startActivity 调用。
下面分别进行分析:
ActivityThread getInstrumentation
调用mMainThread(ActivityThread)的getInstrumentation方法,取得Instrumentation:
//frameworks/base/core/java/android/app/ActivityThread.java
public final class ActivityThread extends ClientTransactionHandler implements ActivityThreadInternal {
Instrumentation mInstrumentation;
public Instrumentation getInstrumentation()
{
return mInstrumentation; //返回mInstrumentationf
}
}
ContextImpl getOuterContext
调用ContextImpl的getOuterContext方法,取得外部Context:
//frameworks/base/core/java/android/app/ContextImpl.java
class ContextImpl extends Context {
private Context mOuterContext;
final Context getOuterContext() {
return mOuterContext; //返回mOuterContext,mOuterContext在ContextImpl构造方法中赋值
}
}
ActivityThread getApplicationThread
调用mMainThread(ActivityThread)的getApplicationThread方法,取得ApplicationThread:
//frameworks/base/core/java/android/app/ActivityThread.java
public final class ActivityThread extends ClientTransactionHandler implements ActivityThreadInternal {
final ApplicationThread mAppThread = new ApplicationThread();
public ApplicationThread getApplicationThread()
{
return mAppThread;
}
}
Instrumentation execStartActivity
调用Instrumentation的execStartActivity方法,执行应用程序发出的startActivity调用:
//frameworks/base/core/java/android/app/Instrumentation.java
public class Instrumentation {
private List<ActivityMonitor> mActivityMonitors; //有关正在监控的特定类型的 Intent 的信息。
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
Uri referrer = target != null ? target.onProvideReferrer() : null;
if (referrer != null) {
intent.putExtra(Intent.EXTRA_REFERRER, referrer);
}
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
for (int i=0; i<N; i++) {
final ActivityMonitor am = mActivityMonitors.get(i);
ActivityResult result = null;
if (am.ignoreMatchingSpecificIntents()) {
if (options == null) {
options = ActivityOptions.makeBasic().toBundle(); //Activity之间实现过渡动画效果
}
result = am.onStartActivity(who, intent, options); //调用ActivityMonitor的onStartActivity方法
}
if (result != null) {
am.mHits++;
return result;
} else if (am.match(who, null, intent)) {
am.mHits++;
if (am.isBlocking()) {
return requestCode >= 0 ? am.getResult() : null;
}
break;
}
}
}
}
try {
intent.migrateExtraStreamToClipData(who);
intent.prepareToLeaveProcess(who);
int result = ActivityTaskManager.getService().startActivity(whoThread,
who.getOpPackageName(), who.getAttributionTag(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()), token,
target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
}
调用ActivityTaskManager的getService方法,获取IActivityTaskManager接口:
//frameworks/base/core/java/android/app/Instrumentation.java
public class Instrumentation {
public static IActivityTaskManager getService() {
return IActivityTaskManagerSingleton.get();
}
}
然后调用IActivityTaskManager接口的startActivity方法,IActivityTaskManager接口由ActivityTaskManagerService实现。
要注意ActivityTaskManagerService不在am目录下而在wm目录下,原因是因为它是在Android 10中引入的新功能,用于管理activities和activity相关容器(task,stacks,display)。为了更好地组织代码和功能,Android团队将ActivityTaskManagerService放置在server/wm目录下,而不是放在server/am目录下。这样可以更清晰地区分和管理不同的服务和功能模块。通过将ActivityTaskManagerService与ActivityManagerService关联起来,可以更好地实现对activity的管理和控制。
ActivityTaskManagerService startActivity
Android13 ActivityTaskManagerService startActivity流程分析-CSDN博客