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标志位。
Activity startActivity流程比较复杂,我们分段介绍,Android系统开机后system_server会先启动AMS,然后启动Launcher,再由Launcher根据用户操作启动对应App的Activity。
AMS启动和Launcher我们不在这里介绍,下面从Launcher调用Activity的startActivity开始,Activity 的startActivity代码如下:
//frameworks/base/core/java/android/app/Activity.java
public class Activity extends ContextThemeWrapper
implements LayoutInflater.Factory2,
Window.Callback, KeyEvent.Callback,
OnCreateContextMenuListener, ComponentCallbacks2,
Window.OnWindowDismissedCallback,
ContentCaptureManager.ContentCaptureClient {
public void startActivity(Intent intent) {
this.startActivity(intent, null);
}
}
调用重载方法:
//frameworks/base/core/java/android/app/Activity.java
public class Activity extends ContextThemeWrapper
implements LayoutInflater.Factory2,
Window.Callback, KeyEvent.Callback,
OnCreateContextMenuListener, ComponentCallbacks2,
Window.OnWindowDismissedCallback,
ContentCaptureManager.ContentCaptureClient {
public void startActivity(Intent intent, @Nullable Bundle options) {
getAutofillClientController().onStartActivity(intent, mIntent);
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
// Note we want to go through this call for compatibility with
// applications that may have overridden the method.
startActivityForResult(intent, -1);
}
}
}
调用startActivityForResult方法:
//frameworks/base/core/java/android/app/Activity.java
public class Activity extends ContextThemeWrapper
implements LayoutInflater.Factory2,
Window.Callback, KeyEvent.Callback,
OnCreateContextMenuListener, ComponentCallbacks2,
Window.OnWindowDismissedCallback,
ContentCaptureManager.ContentCaptureClient {
private Instrumentation mInstrumentation;
ActivityThread mMainThread;
Activity mParent;
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
if (requestCode >= 0) {
// If this start is requesting a result, we can avoid making
// the activity visible until the result is received. Setting
// this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
// activity hidden during this time, to avoid flickering.
// This can only be done when a result is requested because
// that guarantees we will get information back when the
// activity is finished, no matter what happens to it.
mStartedActivity = true;
}
cancelInputsAndStartExitTransition(options);
// TODO Consider clearing/flushing other event sources and events for child windows.
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
// Note we want to go through this method for compatibility with
// existing applications that may have overridden it.
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
}
上面方法主要处理如下:
1、调用Instrumentation的execStartActivity方法,执行应用程序发出的startActivity调用。
2、调用ActivityThread的sendActivityResult方法。
下面分别进行分析:
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
调用ActivityTaskManagerService的startActivity方法,申请启动一个Activity:
Android13 ActivityTaskManagerService startActivity流程分析-CSDN博客
ActivityThread sendActivityResult
调用ActivityThread的sendActivityResult方法,处理Activity之间的结果传递: