「这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战」
前言
Activity启动分析
Activity的启动分为:系统app的启动,用户应用启动时在AndroidManifest.xml中配置以下intent-filter对应的Activity
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
复制代码
和应用打开后启动应用内的Activity。
系统App启动和用户应用的主Activity
android系统启动时,Zygote进程会fork SystemServer进程,SystemServer进程会启动一些系统的服务这就包括了ActivityManagerServic并创建系统上下文。以下是在初始化SystemServer.java时,调用run方法 创建系统上下文的片段,我们可以看到从这里就创建了ActivityThread并进行Attach application
private void createSystemContext() {
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
final Context systemUiContext = activityThread.getSystemUiContext();
systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}
复制代码
下面是ActivityThread中的attach方法。
private void attach(boolean system, long startSeq) {
//......
if (!system) {
//非系统启动
//......
try {
//调用AMS attachApplication
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
//......
} else {
//..........
try {
//.....创建application
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
mInitialApplication.onCreate();
} catch (Exception e) {
}
}
//..........
}
复制代码
attach中的入参boolean system
判断是系统启动时还是用户应用启动。如果是系统启动的话,则会创建Application并调用oncreate方法,如果是用户App启动的话则会调用AMS attachApplication方法,接着调用 attachApplicationLocked方法
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
int pid, int callingUid, long startSeq) {
//......
if (app.getIsolatedEntryPoint() != null) {
// This is an isolated process which should just call an entry point instead of
// being bound to an application.
//这块判断如果是入口点则会运行ActivityThread的main()方法
thread.runIsolatedEntryPoint(
app.getIsolatedEntryPoint(), app.getIsolatedEntryPointArgs());
} else if (instr2 != null) {
//判断 ProcessRecord 是否存在Instrumention对象,如果不为空直接从instrumention获取信息
thread.bindApplication(processName, appInfo, 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);
} else {
thread.bindApplication(processName, appInfo, 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);
}
return true;
}
复制代码
可以看到随后调用了ActivityThread中的bindApplication方法,我们继续跟进bindApplication方法
@Override
public final void bindApplication(....) {
//........
AppBindData data = new AppBindData();
data.processName = processName;
//......
//调用Handler创建Application
sendMessage(H.BIND_APPLICATION, data);
}
public void handleMessage(Message msg) {
switch (msg.what) {
case BIND_APPLICATION:
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
//........
}
复制代码
可以看到最终使用Handler创建application并调用oncreate方法
应用内的Activity启动
从上面已经看到activity启动最终会交付于ATMS的startActivity
@Override
public final int startActivity(..) {
return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
//startActivity最终会调用startActivityAsUser
private int startActivityAsUser(...);
userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
// getActivityStartController().obtainStarter()是一个ActivityStarter对象
return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setCallingFeatureId(callingFeatureId)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setUserId(userId)
.execute();
}
复制代码
至此 又到了StartStarter对象中。执行execute方法。execute最终又调用到了 ActivityStackSupervisor中的realStartActivityLocked方法。
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andResume, boolean checkConfig) throws RemoteException {
//......省略N多代码
// 创建启动activity的事物clientTransaction
final ClientTransaction clientTransaction = ClientTransaction.obtain(
proc.getThread(), r.appToken);
//省略N多代码
//通过ClientLifecycleManager提交事物
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
}
复制代码
我们继续跟进到CLientLifecycleMnager找到scheduleTransaction方法
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();
transaction.schedule();
if (!(client instanceof Binder)) {
// If client is not an instance of Binder - it's a remote call and at this point it is
// safe to recycle the object. All objects used for local calls will be recycled after
// the transaction is executed on client in ActivityThread.
transaction.recycle();
}
}
复制代码
private IApplicationThread mClient;
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}
复制代码
可以看到mClient是applicationThread对象
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}
复制代码
继续从ActivityThread的父类ClientTransactionHandler调用scheduleTransaction
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
//在ActivityThread中使用Handler处理消息
private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction);
break;
// mTransactionExecutor.execute()
public void execute(ClientTransaction transaction) {
final IBinder token = transaction.getActivityToken();
if (token != null) {
final Map<IBinder, ClientTransactionItem> activitiesToBeDestroyed =
mTransactionHandler.getActivitiesToBeDestroyed();
final ClientTransactionItem destroyItem = activitiesToBeDestroyed.get(token);
if (destroyItem != null) {
if (transaction.getLifecycleStateRequest() == destroyItem) {
// It is going to execute the transaction that will destroy activity with the
// token, so the corresponding to-be-destroyed record can be removed.
activitiesToBeDestroyed.remove(token);
}
if (mTransactionHandler.getActivityClient(token) == null) {
// The activity has not been created but has been requested to destroy, so all
// transactions for the token are just like being cancelled.
Slog.w(TAG, tId(transaction) + "Skip pre-destroyed transaction:\n"
+ transactionToString(transaction, mTransactionHandler));
return;
}
}
}
//省略N多代码
executeCallbacks(transaction);
executeLifecycleState(transaction);
}
public void executeCallbacks(ClientTransaction transaction) {
//省略N多代码
// 最开始在ActivityStackSupervisor#realStartActivityLocked中实例化ClientTransaction时 addCallback传入的是LaunchActivityItem; //所以这里执行的其实是LaunchActivityItem.execute方法
item.execute(mTransactionHandler, token, mPendingActions);
item.postExecute(mTransactionHandler, token, mPendingActions);
}
复制代码
从上面代码注释中可以知道我们最终调用的是LaunchActivityItem.execute方法
@Override
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
mPendingResults, mPendingNewIntents, mIsForward,
mProfilerInfo, client, mAssistToken, mFixedRotationAdjustments);
//因为ActivityThread继承ClientTransactionHandler,所以最终 调用了ActivityThread的handleLaunchActivity
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
}
复制代码
handlerActivity中又调用了performLaunchActivity,从下面官网注释中可以发现这是启动activity的核心方法
/** Core implementation of activity launch. */
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
ComponentName component = r.intent.getComponent();
if (component == null) {
component = r.intent.resolveActivity(
mInitialApplication.getPackageManager());
r.intent.setComponent(component);
}
if (r.activityInfo.targetActivity != null) {
component = new ComponentName(r.activityInfo.packageName,
r.activityInfo.targetActivity);
}
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to instantiate activity " + component
+ ": " + e.toString(), e);
}
}
try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
if (localLOGV) Slog.v(
TAG, r + ": app=" + app
+ ", appName=" + app.getPackageName()
+ ", pkg=" + r.packageInfo.getPackageName()
+ ", comp=" + r.intent.getComponent().toShortString()
+ ", dir=" + r.packageInfo.getAppDir());
if (activity != null) {
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
if (r.overrideConfig != null) {
config.updateFrom(r.overrideConfig);
}
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
+ r.activityInfo.name + " with config " + config);
Window window = null;
if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
window = r.mPendingRemoveWindow;
r.mPendingRemoveWindow = null;
r.mPendingRemoveWindowManager = null;
}
// Activity resources must be initialized with the same loaders as the
// application context.
appContext.getResources().addLoaders(
app.getResources().getLoaders().toArray(new ResourcesLoader[0]));
appContext.setOuterContext(activity);
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback,
r.assistToken);
if (customIntent != null) {
activity.mIntent = customIntent;
}
r.lastNonConfigurationInstances = null;
checkAndBlockForNetworkAccess();
activity.mStartedActivity = false;
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
if (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onCreate()");
}
r.activity = activity;
mLastReportedWindowingMode.put(activity.getActivityToken(),
config.windowConfiguration.getWindowingMode());
}
r.setState(ON_CREATE);
// updatePendingActivityConfiguration() reads from mActivities to update
// ActivityClientRecord which runs in a different thread. Protect modifications to
// mActivities to avoid race.
synchronized (mResourcesManager) {
mActivities.put(r.token, r);
}
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to start activity " + component
+ ": " + e.toString(), e);
}
}
return activity;
}
复制代码
从上面代码中可以看到我们应用中重要的application window的身影还有activity的attach调用。至此activity已经完全启动
//啊 终于完了历时两天 太累了。。。。。。。。。。。。。里面还有很多细节 分析不了了。。