Activity框架03-ActivityThread
Tip
基于 android-14.0.0_r45
背景¶
在 app 的冷启动流程中,AMS 会通过 startProcess() 方法一路调到 ProcessList.startProcessLocked() 方法,并设置 entryPoint 为 ActivityThread;并通过 socket 通信把消息发送给 Zygote 进程。
Zygote 进程的 ZygoteServer 接到信息后,解析出传过来的 entryPoint 并保存在 Arguments 的成员变量 startClass 中;最终通过反射的方式去反射其 main() 方法。也就是 ActivityThread.main() 。
所以 ActivityThread 是 app 进程的主入口。
类图¶
ActivityThread¶
plantuml(点击展开详情)
mermaid
classDiagram
direction BT
class ActivityClientRecord {
+ ActivityClientRecord()
+ ActivityClientRecord(IBinder)
+ IBinder token
~ Activity activity
- int mLifecycleState
- init() void
+ setState(int) void
+ getLifecycleState() int
}
class ActivityThread {
+ ActivityThread()
~ H mH
~ Instrumentation mInstrumentation
~ ApplicationThread mAppThread
~ Looper mLooper
~ ArrayMap~IBinder, ActivityClientRecord~ mActivities
- performStopActivityInner(ActivityClientRecord, StopInfo, boolean, boolean, String) void
- sendMessage(int, Object, int, int, boolean) void
+ handleStartActivity(ActivityClientRecord, PendingTransactionActions, ActivityOptions) void
+ handleLaunchActivity(ActivityClientRecord, PendingTransactionActions, int, Intent) Activity?
+ handleResumeActivity(ActivityClientRecord, boolean, boolean, boolean, String) void
- performPauseActivity(ActivityClientRecord, boolean, String, PendingTransactionActions) Bundle?
+ handlePauseActivity(ActivityClientRecord, boolean, boolean, int, boolean, PendingTransactionActions, String) void
+ handleDestroyActivity(ActivityClientRecord, boolean, int, boolean, String) void
+ performResumeActivity(ActivityClientRecord, boolean, String) boolean
~ performDestroyActivity(ActivityClientRecord, boolean, int, boolean, String) void
+ main(String[]) void
- performLaunchActivity(ActivityClientRecord, Intent) Activity
+ getActivity(IBinder) Activity?
~ sendMessage(int, Object) void
+ handleStopActivity(ActivityClientRecord, int, PendingTransactionActions, boolean, String) void
+ getActivityClient(IBinder) ActivityClientRecord
- attach(boolean, long) void
}
class ApplicationThread {
+ ApplicationThread()
+ bindApplication(String, ApplicationInfo) void
}
class ClientTransactionHandler {
+ ClientTransactionHandler()
+ getActivity(IBinder) Activity
+ handleStartActivity(ActivityClientRecord, PendingTransactionActions, ActivityOptions) void
+ handleRelaunchActivity(ActivityClientRecord, PendingTransactionActions) void
+ handleResumeActivity(ActivityClientRecord, boolean, boolean, boolean, String) void
~ sendMessage(int, Object) void
+ getActivityClient(IBinder) ActivityClientRecord
+ handleStopActivity(ActivityClientRecord, int, PendingTransactionActions, boolean, String) void
~ scheduleTransaction(ClientTransaction) void
+ handleDestroyActivity(ActivityClientRecord, boolean, int, boolean, String) void
+ handlePauseActivity(ActivityClientRecord, boolean, boolean, int, boolean, PendingTransactionActions, String) void
+ handleLaunchActivity(ActivityClientRecord, PendingTransactionActions, int, Intent) Activity
}
class Default {
+ Default()
+ bindApplication(String, ApplicationInfo) void
+ asBinder() IBinder
}
class H {
+ H()
+ int BIND_APPLICATION
+ handleMessage(Message) void
}
class IApplicationThread {
<<Interface>>
+ bindApplication(String, ApplicationInfo) void
}
class Proxy {
~ Proxy(IBinder)
- IBinder mRemote
+ bindApplication(String, ApplicationInfo) void
+ asBinder() IBinder
+ getInterfaceDescriptor() String
}
class Stub {
+ Stub()
+ String DESCRIPTOR
~ int TRANSACTION_bindApplication
+ getDefaultTransactionName(int) String?
+ asInterface(IBinder) IApplicationThread
+ asBinder() IBinder
+ getTransactionName(int) String
+ onTransact(int, Parcel, Parcel, int) boolean
}
ActivityThread --> ActivityClientRecord
ActivityThread --> ClientTransactionHandler
ActivityThread --> ApplicationThread
ApplicationThread --> Stub
IApplicationThread --> Default
Default ..> IApplicationThread
ActivityThread --> H
Proxy ..> IApplicationThread
Stub --> Proxy
Stub ..> IApplicationThread
IApplicationThread --> Stub
ActivityThread 有几个比较重要的成员变量:
-
mAppThread
其类型为 ApplicationThread
-
mH
其类型为 Handler
-
mInstrumentation
其类型为 Instrumentation
-
mActivities
其类型为 ArrayMap
<IBinder, ActivityClientRecord>
ActivityThread 的两个内部类:
- H(Handler)
- ApplicationThread
Instrumentation¶
plantuml(点击展开详情)
mermaid
classDiagram
direction BT
class Instrumentation {
- Context mAppContext
- ActivityThread mThread
+ callActivityOnCreate(Activity, Bundle) void
+ callActivityOnStop(Activity) void
+ callActivityOnPause(Activity) void
+ getContext() Context
+ callActivityOnPostCreate(Activity, Bundle, PersistableBundle) void
+ callActivityOnPostCreate(Activity, Bundle) void
+ callApplicationOnCreate(Application) void
+ execStartActivity(Context, IBinder, IBinder, Activity, Intent, int, Bundle) ActivityResult
+ newActivity(ClassLoader, String, Intent) Activity
+ callActivityOnDestroy(Activity) void
+ callActivityOnResume(Activity) void
+ callActivityOnCreate(Activity, Bundle, PersistableBundle) void
+ callActivityOnStart(Activity) void
+ newApplication(Class~?~, Context) Application
+ newApplication(ClassLoader, String, Context) Application
}
ActivityThread核心代码¶
public final class ActivityThread extends ClientTransactionHandler
implements ActivityThreadInternal {
@UnsupportedAppUsage
final ApplicationThread mAppThread = new ApplicationThread();
@UnsupportedAppUsage
final H mH = new H();
/**
* The activities to be truly destroyed (not include relaunch). */ final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>();
@UnsupportedAppUsage
Instrumentation mInstrumentation;
public static final class ActivityClientRecord {
@UnsupportedAppUsage
public IBinder token;
@UnsupportedAppUsage
Activity activity;
@LifecycleState
private int mLifecycleState = PRE_ON_CREATE;
public ActivityClientRecord(IBinder token, Intent intent, int ident,
ActivityInfo info, Configuration overrideConfig,
String referrer, IVoiceInteractor voiceInteractor, Bundle state,
PersistableBundle persistentState, List<ResultInfo> pendingResults,
List<ReferrerIntent> pendingNewIntents, ActivityOptions activityOptions,
boolean isForward, ProfilerInfo profilerInfo, ClientTransactionHandler client,
IBinder assistToken, IBinder shareableActivityToken, boolean launchedFromBubble,
IBinder taskFragmentToken) {
this.token = token;
}
public int getLifecycleState() {
return mLifecycleState;
}
public void setState(@LifecycleState int newLifecycleState) {
mLifecycleState = newLifecycleState;
}
}
private class ApplicationThread extends IApplicationThread.Stub {
@Override
public final void bindApplication(String processName, ApplicationInfo appInfo,
String sdkSandboxClientAppVolumeUuid, String sdkSandboxClientAppPackage,
ProviderInfoList providerList, ComponentName instrumentationName,
ProfilerInfo profilerInfo, Bundle instrumentationArgs,
IInstrumentationWatcher instrumentationWatcher,
IUiAutomationConnection instrumentationUiConnection, int debugMode,
boolean enableBinderTracking, boolean trackAllocation,
boolean isRestrictedBackupMode, boolean persistent, Configuration config,
CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
String buildSerial, AutofillOptions autofillOptions,
ContentCaptureOptions contentCaptureOptions, long[] disabledCompatChanges,
SharedMemory serializedSystemFontMap,
long startRequestedElapsedTime, long startRequestedUptime) {
sendMessage(H.BIND_APPLICATION, data);
}
}
class H extends Handler {
public static final int BIND_APPLICATION = 110;
public void handleMessage(Message msg) {
switch (msg.what) {
case BIND_APPLICATION:
AppBindData data = (AppBindData) msg.obj;
handleBindApplication(data);
break;
}
}
}
@UnsupportedAppUsage
private void handleBindApplication(AppBindData data) {
}
void sendMessage(int what, Object obj) {
sendMessage(what, obj, 0, 0, false);
}
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
if (async) {
msg.setAsynchronous(true);
}
mH.sendMessage(msg);
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
}
@Override
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, int deviceId, Intent customIntent) {
return null;
}
public static void main(String[] args) {
}
}
ActivityThread.main()¶
public static void main(String[] args) {
...
// 创建ActivityThread实例
ActivityThread thread = new ActivityThread();
// 附加到ActivityThread实例并传递startSeq
thread.attach(false, startSeq);
...
// 启动Looper循环,开始处理消息
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
这里很简单,就是创建 ActivityThread 实例,并调用其 attach() 方法。
ActivityThread.attach()¶
private void attach(boolean system, long startSeq) {
...
if (!system) {
...
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
...
} else {
...
}
...
}
通过 IActivityManager 跟 AMS 进行 binder 通讯。 其中 mAppThread 就是 ActivityThread 的内部类 ApplicationThread 。
ActivityManagerService.attachApplication()¶
@Override
public final void attachApplication(IApplicationThread thread, long startSeq) {
if (thread == null) {
throw new SecurityException("Invalid application interface");
}
synchronized (this) {
int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid, callingUid, startSeq);
Binder.restoreCallingIdentity(origId);
}
}
这里的 thread 就是前面传进来的 mAppThread ,也就是 ApplicationThread 。这样 AMS 就拿到了客户端的 binder 对象,就可以通过这个对象跟客户端进程 ipc 通讯了。
AMS与ActivityThread通讯¶
前面我们分析到了 AMS 拿到客户端的 binder 对象,那么我们现在来分析 AMS 是如何调用到客户端的。
ActivityManagerService.attachApplicationLocked()¶
private void attachApplicationLocked(@NonNull IApplicationThread thread,
int pid, int callingUid, long startSeq) {
...
try {
...
if (app.getIsolatedEntryPoint() != null) {
// This is an isolated process which should just call an entry point instead of
// being bound to an application. thread.runIsolatedEntryPoint(
app.getIsolatedEntryPoint(), app.getIsolatedEntryPointArgs());
} else if (instr2 != null) {
thread.bindApplication(processName, appInfo,
app.sdkSandboxClientAppVolumeUuid, app.sdkSandboxClientAppPackage,
providerList,
instr2.mClass,
profilerInfo, instr2.mArguments,
instr2.mWatcher,
instr2.mUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.isPersistent(),
new Configuration(app.getWindowProcessController().getConfiguration()),
app.getCompat(), getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, autofillOptions, contentCaptureOptions,
app.getDisabledCompatChanges(), serializedSystemFontMap,
app.getStartElapsedTime(), app.getStartUptime());
} else {
thread.bindApplication(processName, appInfo,
app.sdkSandboxClientAppVolumeUuid, app.sdkSandboxClientAppPackage,
providerList, null, profilerInfo, null, null, null, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.isPersistent(),
new Configuration(app.getWindowProcessController().getConfiguration()),
app.getCompat(), getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, autofillOptions, contentCaptureOptions,
app.getDisabledCompatChanges(), serializedSystemFontMap,
app.getStartElapsedTime(), app.getStartUptime());
}
...
} catch (Exception e) {
...
return;
}
}
现在我们只需知道,这段程序会走到 else 即可。
因为 ApplicationThread 继承了 IApplicationThread.Stub ,使用这里就可以通过 binder 调用到 ApplicationThread 的 bindApplication() 方法中。
ApplicationThread.bindApplication()¶
private class ApplicationThread extends IApplicationThread.Stub {
@Override
public final void bindApplication(String processName, ApplicationInfo appInfo,
String sdkSandboxClientAppVolumeUuid, String sdkSandboxClientAppPackage,
ProviderInfoList providerList, ComponentName instrumentationName,
ProfilerInfo profilerInfo, Bundle instrumentationArgs,
IInstrumentationWatcher instrumentationWatcher,
IUiAutomationConnection instrumentationUiConnection, int debugMode,
boolean enableBinderTracking, boolean trackAllocation,
boolean isRestrictedBackupMode, boolean persistent, Configuration config,
CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
String buildSerial, AutofillOptions autofillOptions,
ContentCaptureOptions contentCaptureOptions, long[] disabledCompatChanges,
SharedMemory serializedSystemFontMap,
long startRequestedElapsedTime, long startRequestedUptime) {
...
sendMessage(ActivityThread.H.BIND_APPLICATION, data);
}
}
所以需要切到主线去操作。
主线程¶
子线程切换到主线程的操作就很简单了,做过 Android 开发的对 Handler 的使用都不陌生。
前面讲到的 ApplicationThread.bindApplication() ,最后是通过调用 sendMessage() 给 Handler 发送一条消息。
ActivityThread.sendMessage()¶
private void sendMessage(int what, Object obj, int arg1, int arg2) {
sendMessage(what, obj, arg1, arg2, false);
}
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
if (async) {
msg.setAsynchronous(true);
}
mH.sendMessage(msg);
}
这里的 mH 就是 ActivityThread 的一个内部类 H(Handler)
H.handleMessage()¶
public final class ActivityThread extends ClientTransactionHandler
implements ActivityThreadInternal {
@UnsupportedAppUsage
final H mH = new H();
class H extends Handler {
public static final int BIND_APPLICATION = 110;
public void handleMessage(Message msg) {
switch (msg.what) {
case BIND_APPLICATION:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
}
}
}
}
H 类接到消息后,调用 ActivityThread.handleBindApplication()。 所以 handleBindApplication() 方法就运行在主线程中了。
Instrumentation¶
Instrumentation 的初始化就是在 ActivityThread.handleBindApplication() 中进行的。
private void handleBindApplication(AppBindData data) {
...
// Instrumentation info affects the class loader, so load it before
// setting up the app context. final InstrumentationInfo ii;
if (data.instrumentationName != null) {
ii = prepareInstrumentation(data);
} else {
ii = null;
}
...
// Continue loading instrumentation.
if (ii != null) {
initInstrumentation(ii, data, appContext);
} else {
mInstrumentation = new Instrumentation();
mInstrumentation.basicInit(this);
}
try {
...
// Do this after providers, since instrumentation tests generally start their
// test thread at this point, and we don't want that racing. try {
mInstrumentation.onCreate(data.instrumentationArgs);
}
catch (Exception e) {
throw new RuntimeException(
"Exception thrown in onCreate() of "
+ data.instrumentationName + ": " + e.toString(), e);
}
try {
mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
if (!mInstrumentation.onException(app, e)) {
throw new RuntimeException(
"Unable to create application " + app.getClass().getName()
+ ": " + e.toString(), e);
}
}
} finally {
...
}
...
}
AMS 调用 ApplicationThread.bindApplication() 传进来的 ComponentName testName 是 null ,所以这里的 data.instrumentationName 是 null 。
所有这段代码最终是调
初始化 Instrumentation。前面的类图也提到了ActivityThread 有一个重要的成员变量 mInstrumentation。 ActivityThread 调用 Activity 的生命周期就是通过 Instrumentation 做个执行的。
ActivityThread执行Activity生命周期¶
在前面的 Activity框架01-客户端事务管理 分析中,我们提到了 system_server 会通过ClientTransaction 调用到每个 item 的 execute(),从而走到 ActivityThread 去执行 Activity 的生命周期。
之前我们只是一笔带过,没有去分析 ActivityThread 如何调用 Activity 的生命周期,这次我们就来分析这一细节。
ActivityThread.handleLaunchActivity()¶
@Override
public Activity handleLaunchActivity(ActivityThread.ActivityClientRecord r,
PendingTransactionActions pendingActions, int deviceId, Intent customIntent) {
...
final Activity a = performLaunchActivity(r, customIntent);
...
return a;
}
我们接着看 performLaunchActivity()。
ActivityThread.performLaunchActivity()¶
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo;
...
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
...
} catch (Exception e) {
...
}
try {
Application app = r.packageInfo.makeApplicationInner(false, mInstrumentation);
...
synchronized (mResourcesManager) {
mActivities.put(r.token, r);
}
if (activity != null) {
...
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
...
}
...
} catch (SuperNotCalledException e) {
...
} catch (Exception e) {
...
}
return activity;
}
这里只保留 performLaunchActivity() 核心代码,我们这里只关心 Activity。
首先是通过 Instrumentation.newActivity() 去创建一个 Activity;其次再通过 Instrumentation.callActivityOnCreate() 去调用 Activity 的 onCreate() 方法。
Instrumentation.newActivity()¶
public Activity newActivity(ClassLoader cl, String className,
Intent intent)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
// 获取包名,如果intent和其组件不为空,则获取组件的包名,否则为null
String pkg = intent != null && intent.getComponent() != null
? intent.getComponent().getPackageName() : null;
// 使用包名获取对应的AppComponentFactory,并通过它来实例化Activity
return getFactory(pkg).instantiateActivity(cl, className, intent);
}
private AppComponentFactory getFactory(String pkg) {
// 如果包名为null,输出错误日志,并返回默认的AppComponentFactory
if (pkg == null) {
Log.e(TAG, "No pkg specified, disabling AppComponentFactory");
return AppComponentFactory.DEFAULT;
}
// 如果ActivityThread未初始化,输出错误日志,并返回默认的AppComponentFactory
if (mThread == null) {
Log.e(TAG, "Uninitialized ActivityThread, likely app-created Instrumentation,"
+ " disabling AppComponentFactory", new Throwable());
return AppComponentFactory.DEFAULT;
}
// 通过包名获取LoadedApk对象
LoadedApk apk = mThread.peekPackageInfo(pkg, true);
// 如果获取到的apk为null,获取系统上下文的PackageInfo
if (apk == null) apk = mThread.getSystemContext().mPackageInfo;
// 返回apk对应的AppComponentFactory
return apk.getAppFactory();
}
AppComponentFactory.instantiateActivity()¶
public class AppComponentFactory {
/**
* 允许应用程序覆盖Activity的创建。这可以用于执行诸如依赖注入或类加载器
* 更改等操作。
*
* <p>此方法仅用于提供实例化的钩子。它不会提供对Activity对象的提前访问。
* 返回的对象尚未初始化为Context,不应用于与其他Android API交互。
*
* @param cl 用于实例化的默认类加载器。
* @param className 要实例化的类名。
* @param intent 创建类的Intent。
* @return 新创建的Activity实例。
* @throws InstantiationException 如果无法实例化类。
* @throws IllegalAccessException 如果没有权限访问类或其空构造函数。
* @throws ClassNotFoundException 如果找不到类。
*/
public @NonNull Activity instantiateActivity(@NonNull ClassLoader cl, @NonNull String className,
@Nullable Intent intent)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
// 使用指定的类加载器加载类,并创建该类的新实例
return (Activity) cl.loadClass(className).newInstance();
}
}
使用传入的类加载器加载指定的类,并通过调用 newInstance() 方法创建该类的新实例。
Instrumentation.callActivityOnCreate()¶
/**
* 调用一个活动(Activity)的 {@link Activity#onCreate} 方法。
* 默认实现只是简单地调用该方法。
*
* @param activity 正在创建的活动实例。
* @param icicle 之前冻结的状态(或者为 null),将传递给 onCreate() 方法。
*/
public void callActivityOnCreate(Activity activity, Bundle icicle) {
// 在调用活动的 onCreate() 方法之前进行的操作。
prePerformCreate(activity);
// 调用活动的 performCreate() 方法,这实际上是调用活动的 onCreate() 方法。
activity.performCreate(icicle);
// 在调用活动的 onCreate() 方法之后进行的操作。
postPerformCreate(activity);
}
Activity.performCreate()¶
final void performCreate(Bundle icicle) {
performCreate(icicle, null);
}
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
...
if (persistentState != null) {
onCreate(icicle, persistentState);
} else {
onCreate(icicle);
}
...
}
Activity.onCreate()¶
@MainThread
@CallSuper
protected void onCreate(@Nullable Bundle savedInstanceState) {
}
public void onCreate(@Nullable Bundle savedInstanceState,
@Nullable PersistableBundle persistentState) {
onCreate(savedInstanceState);
}
总结¶
-
ActivityThread 的内部类 ApplicationThread 是继承 IApplicationThread.Stub,主要是通过 AMS 与客户端通信的通道。
-
ActivityThread 的内部类 H(Handler) 主要是把 binder 线程切到主线程再做对应的操作。
-
ActivityThread 的内部类 ActivityClientRecord 是 app 端 Activity 和 ActivityClientRecord 是一一对应的。在 Activity框架02-ActivityClientRecord 有详细分析。
-
ActivityThread 通过成员变量 mInstrumentation 来创建 Activity 并调用其生命周期。