Activity启动流程(基于AOSP 11)

1,758 阅读10分钟

当点击Launcher的App icon的时候,点击事件传递给ItemClickHandler的onClickAppShortcut,并最终调用到launcher.startActivitySafely->BaseDraggingActivity.startActivitySafely:

    public boolean startActivitySafely(View v, Intent intent, @Nullable ItemInfo item,
            @Nullable String sourceContainer) {
        // ...
        // 将Intent的Flag设置为FLAG_ACTIVITY_NEW_TASK
        // 这样启动Activity就会在一个新的Activity任务栈中
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        // ...
        try {
            // ... 省略一些快捷方式启动
            else if (user == null || user.equals(Process.myUserHandle())) {
                // Could be launching some bookkeeping activity
                // 启动应用Activity
                startActivity(intent, optsBundle);
                AppLaunchTracker.INSTANCE.get(this).onStartApp(intent.getComponent(),
                        Process.myUserHandle(), sourceContainer);
            }
            // ...
            return true;
        } catch (NullPointerException|ActivityNotFoundException|SecurityException e) {
            Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
            Log.e(TAG, "Unable to launch. tag=" + item + " intent=" + intent, e);
        }
        return false;
    }

startActivity的实现位于Activity中:

    public void startActivity(Intent intent, @Nullable Bundle options) {
        // ... 都是调用startActivityForResult启动Activity
        // 传入的requestCode是-1
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {
            startActivityForResult(intent, -1);
        }
    }

启动Activity最终通过Instrumentation的execStartActivity方法启动,而Instrumentation的作用其实是监控应用和系统交互的中间这,是安卓提供的一层Hook操作,让开发者有能力介入到Activity的各项声明周期中,比如可以用来测试,Activity的各项生命周期的回调也是通过这个类作为中间层实现的,execStartActivity核心是调用到:

int result = ActivityTaskManager.getService().startActivity(whoThread,
who.getBasePackageName(), who.getAttributionTag(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()), token,
target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);

ActivityTaskManager是Android 10中新增加的一个类,接替了ActivityManager中Activity与ActivityTask交互的工作,而ActivitTaskManager.getService返回的就是IActivityTaskManager这个AIDL文件中声明的接口,而SystemServer进程中的系统服务ActivityTaskManagerService只需要继承IActivityTaskManager.Stub就可以实现用户进程与服务进程的通信。

new Singleton<IActivityTaskManager>() {
	@Override
	protected IActivityTaskManager create() {
		final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
		return IActivityTaskManager.Stub.asInterface(b);
		}
};

首先获取到SystemServer进程中ActivityTaskManagerService这个系统服务的IBinder接口,然后将这个IBinder接口转换为IActivityTaskManager接口,这样引用进程就可以调用到IActivityTaskManager的方法,与ATMS进行通信了。

那么应用进程调用startActivity终于还是调用到ATMS的startActivity方法了,到这里,创建Activity的逻辑就从Launcher进程进入到了ATMS所在的SystemServer进程:

在ATMS的startActivity中,调用到ATMS.startActivityAsUser:

    private int startActivityAsUser(IApplicationThread caller, String callingPackage,
            @Nullable String callingFeatureId, Intent intent, String resolvedType,
            IBinder resultTo, String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
        // 前置权限校验
        // 下面获取ActivityStart对象
        // 这个对象是控制Activity启动的代理对象
        // 7.0以后加入,收集Activity启动相关的各种参数逻辑
        // 决定如何启动Activity一级Activity的Task和TaskStack关联
        return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
                // ... 设置了很多参数
                .execute();

    }

在对ActivityStarter对象设置完一堆参数之后,调用其execute执行启动:

    int execute() {
        try {
            // ...
            int res;
            synchronized (mService.mGlobalLock) {
                // ...
                // 启动信息都在mRequest中了,执行这个请求
                res = executeRequest(mRequest);
								// 启动完成之后的一些通知等工作......
            }
        } finally {
            onExecutionComplete();
        }
    }

executeRequest里边的逻辑很多,主要包含各种校验逻辑,比如检验启动参数,Flag等,总之,正常启动流程会去根据各种启动参数创建一个ActivityRecord对象,ActivityRecord对象就代表着一个在任务栈中的Activity实体,最后调用到ActivityStarter的startActivityUnchecked。

startActivityUnchecked->startActivityInner,在startActivityInner中,会先去对Activity启动Flag进行各种校验,比如如果启动的是一个根Activity,但是启动Flag并不是FLAG_ACTIVITY_NEW_TASK,那么会将LaunchFlag修改为FLAG_ACTIVITY_NEW_TASK。然后找到是否有可以重用的任务栈,如果没有,会去创建一个新的任务栈,在startActivityInner中关于启动的核心逻辑是调用:

mRootWindowContainer.resumeFocusedStacksTopActivities(
                        mTargetStack, mStartActivity, mOptions);

RootWindowContainer是在WMS中创建的对象,可以理解为其管理者屏幕显示的内容。在RootWindowContainer中,会调用到ActivityStack的resumeTopActivityUncheckedLocked->resumeTopActivityInnerLocked。这个方法在11上长达400+行,逻辑很多,和我们要分析的主流程相关的重点如下:

// attachedToProcess的判断逻辑:要启动的Activity的进程是否存在以及
// 对应进程的ActivityThread是否存在,而我们这里启动的是一个新进程
// 的根Activity,此时新进程还未创建以及ActivityRecord还没有绑定到新进程中
if (next.attachedToProcess()) {
  // ...
} else {
  // ...
  mStackSupervisor.startSpecificActivity(next, true, true);
}

ActivityStackSupervisor的startSpecificActivity如下:

    void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?
        final WindowProcessController wpc =
                mService.getProcessController(r.processName, r.info.applicationInfo.uid);

        boolean knownToBeDead = false;
        // 如果应用所在的进程已经存在,那么执行realStartActivityLocked
        // 进行Activity启动
        if (wpc != null && wpc.hasThread()) {
            try {
                // 这个函数后面再做分析
                realStartActivityLocked(r, wpc, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }

            // If a dead object exception was thrown -- fall through to
            // restart the application.
            knownToBeDead = true;
        }

        r.notifyUnknownVisibilityLaunchedForKeyguardTransition();

        final boolean isTop = andResume && r.isTopRunningActivity();
        // 如果应用进程不存在,ATMS(最终是AMS)将会异步启动应用进程
        mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
    }

对于应用进程不存在的情况,AMS会往SystemServer的消息队列中发送一个Lambda类型的Message(其实就是类似Runnable类型的消息),然后消息执行的时候,调用关系:

AMS.startProcessAsync->AMS.startProcess->AMS.startProcessLocked->ProcessList.startProcessLocked...->ProcessList.startProcess->Process.start,最终通过ZygoteProcess调用startViaZygote,通过Zygote进程fork出应用进程,完成应用进程的创建,在应用进程创建的同时,会往SystemServer的消息队列中发送一条超时消息(默认10s),超时到了应用进程仍然未启动的话,就会杀死这个启动失败的进程。

而在Zygote fork出子进程之后,就会执行到ActivityThrea的main方法,在ActivityThread的main方法中,做的最重要的两件事,开启主线程的Looper机制和创建ActivityThread并调用ActivityThread的attach函数,其中:

// mAppThread是ApplicationThread对象,在ActivityThread被创建的时候创建
// 是AMS与应用进程通信的桥梁
// 这里初始化RuntimeInit.mApplicationObject值
RuntimeInit.setApplicationObject(mAppThread.asBinder());
// 获取到AMS的Binder接口IActivityManager
final IActivityManager mgr = ActivityManager.getService();
try {
  // 调用AMS的attachApplication
	mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
	throw ex.rethrowFromSystemServer();
}

AMS中attachApplication实现如下:

    public final void attachApplication(IApplicationThread thread, long startSeq) {
        // 如果传入的ApplicationThread是空的,那么就会异常终止应用进程
        if (thread == null) {
            throw new SecurityException("Invalid application interface");
        }
        synchronized (this) {
            // 获取binder调用方进程的pid和uid,这里的调用方就是应用进程
            int callingPid = Binder.getCallingPid();
            final int callingUid = Binder.getCallingUid();
            // 修改binder调用端的pid、uid为调用进程的pid、uid,并返回原uid和pid的组合
            // 高32位表示上面的uid,低32位表示pid
            final long origId = Binder.clearCallingIdentity();
            attachApplicationLocked(thread, callingPid, callingUid, startSeq);
            // 恢复pid、uid
            Binder.restoreCallingIdentity(origId);
        }
    }

attachApplicationLocked又是一个超长函数,内部主要是对App进程做一些检查设置等工作。

// 内部首先会去查找有没有旧的进程记录,如果有,做一些清理类的工作
// ...
// 然后比如debug模式也会做一些特殊的设置工作
// ...
// 再比如建立Binder死亡回调,当进AMS所在服务程异常退出的时候,
// Binder驱动可以通知到应用进程,并释放死亡进程锁占用的没有正常关闭的binder文件。
// 当SystemServer进程因为异常挂掉的时候,是有重启机制的
// ...
// 移除在AMS启动进程的过程中埋下的PROC_START_TIMEOUT_MSG消息
mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
// ...
// IPC调用应用进程ApplicationThread的bindApplication:
thread.bindApplication(...);

AMS在完成对ApplicationThread一些设置工作后,会回到应用进程的bindApplication,bindApplication的时候,AMS会将一些通用的系统服务传递给应用进程,比如WMS,IMS等等。

public final void bindApplication(...) {
	if (services != null) {
	// 将AMS传过来的通用系统服务缓存到ServiceManager的
	// 静态cache中
	ServiceManager.initServiceCache(services);
	}
	// 通过ActivityThread的H(继承自Handler)
	// 发送一条SET_CORE_SETTINGS的消息给主线程,
  // 将coreSettings设置给ActivityThread对象
  // 并触发当前进程所有Activity的重启(因为ActivityThread的核心设置被修改了)
	setCoreSettings(coreSettings);
  // AppBindData是bindApplication的一堆数据的封装
	AppBindData data = new AppBindData();
  // 通过mH发送BIND_APPLICATION消息给主线程
	sendMessage(H.BIND_APPLICATION, data);
}

下面bindApplication的逻辑进入H中,H是ActivityThread中的自定义Handler,比如Service的创建,绑定,Activity的生命周期处理都在这里边:

而对于BIND_APPLICATION,handleMessage将调用到handleBindApplication。

在handleBindApplication中,会填充data.info字段,其实是LoadApk对象,通过getPackageInfo获取,其包含了比如mPackagerName应用包名,mDataDir应用数据目录,mResources,mApplication等信息。

然后是完成Context的创建:

final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
// createAppContext
static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo,
	String opPackageName) {
	if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
  // 创建ContextImpl对象,初始化了ApplicationContext的mMainThread、packageInfo等字段
  // 在ContextImpl的构造方法中,还创建了ApplicationContentResolver这个对象
	ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, null,
		0, null, opPackageName);
	context.setResources(packageInfo.getResources());
  // 是否是系统状态栏的Context
	context.mIsSystemOrSystemUiContext = isSystemOrSystemUI(context);
	return context;
}

完成Context的创建之后,后面会继续Application对象的创建,还是在handleBindApplication中:

Application app;
// ...
app = data.info.makeApplication(data.restrictedBackupMode, null);

// LoadedApk.makeApplication:
// ...
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
// 调用newApplication创建Application对象
app = mActivityThread.mInstrumentation.newApplication(
	cl, appClass, appContext);
// ...
// 将Application赋值给LoadedApk的mApplication,并添加到ActivityThread的Application列表
mApplication = app;

在newApplication中:

public Application newApplication(ClassLoader cl, String className, Context context)
	throws InstantiationException, IllegalAccessException, 
		ClassNotFoundException {
  // 内部就是反射Application Class的newInstance
	Application app = getFactory(context.getPackageName())
	.instantiateApplication(cl, className);
  // 将Context对象绑定给Application
	app.attach(context);
	return app;
}

// attach如下:
final void attach(Context context) {
  // attachBaseContext就是将context赋值给Application(继承自ContextWrapper的)的mBase字段
	attachBaseContext(context);
	mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}

继续回到应用进程的handleBindApplication中,在创建完Application对象之后:

// 回调到Application对象的onCreate方法
mInstrumentation.callApplicationOnCreate(app);

应用进程终于创建完成了,现在我们回到AMS的attachApplicationLocked中,在bindApplication完成Application对象的创建之后:

// 如果Application有待启动的Activity,那么执行Activity的启动
// 对于我们从Launcher中点击icon启动一个App来说,创建完新的进程和Application之后
// 就需要启动MainActivity
if (normalMode) {
	try {
		didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
	} catch (Exception e) {
		Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
		badApp = true;
	}
}
// ActivityTaskManagerService的内部类LocalService实现的attachApplication方法:
// 内部调用
mRootWindowContainer.attachApplication(wpc);

RootWindowContainer.attachApplication如下:

    boolean attachApplication(WindowProcessController app) throws RemoteException {
        boolean didSomething = false;
        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
            mTmpRemoteException = null;
            mTmpBoolean = false; // Set to true if an activity was started.

            final DisplayContent display = getChildAt(displayNdx);
            for (int areaNdx = display.getTaskDisplayAreaCount() - 1; areaNdx >= 0; --areaNdx) {
                final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(areaNdx);
                for (int taskNdx = taskDisplayArea.getStackCount() - 1; taskNdx >= 0; --taskNdx) {
                    final ActivityStack rootTask = taskDisplayArea.getStackAt(taskNdx);
                    if (rootTask.getVisibility(null /*starting*/) == STACK_VISIBILITY_INVISIBLE) {
                        break;
                    }
                    // 找到待启动的ActivityRecord,然后
                    // 调用startActivityForAttachedApplicationIfNeeded
                    final PooledFunction c = PooledLambda.obtainFunction(
                            RootWindowContainer::startActivityForAttachedApplicationIfNeeded, this,
                            PooledLambda.__(ActivityRecord.class), app,
                            rootTask.topRunningActivity());
                    rootTask.forAllActivities(c);
                    c.recycle();
                    if (mTmpRemoteException != null) {
                        throw mTmpRemoteException;
                    }
                }
            }
            didSomething |= mTmpBoolean;
        }
        if (!didSomething) {
            ensureActivitiesVisible(null, 0, false /* preserve_windows */);
        }
        return didSomething;
    }

而startActivityForAttachedApplicationIfNeeded的实现,就是把我们找到的待启动的ActivityRecord,调用到mStackSupervisor.realStartActivityLocked。

回到ActivityStackSupervisor的startSpecificActivity:

    void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?
        final WindowProcessController wpc =
                mService.getProcessController(r.processName, r.info.applicationInfo.uid);

        boolean knownToBeDead = false;
        // 如果应用所在的进程已经存在,那么执行realStartActivityLocked
        // 进行Activity启动
        if (wpc != null && wpc.hasThread()) {
            try {
                // 这个函数后面再做分析
                realStartActivityLocked(r, wpc, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }

            // If a dead object exception was thrown -- fall through to
            // restart the application.
            knownToBeDead = true;
        }

        r.notifyUnknownVisibilityLaunchedForKeyguardTransition();

        final boolean isTop = andResume && r.isTopRunningActivity();
        // 如果应用进程不存在,ATMS(最终是AMS)将会异步启动应用进程
        mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
    }

AMS在调用到mService.startProcessAsync启动一个新的应用进程之后,最终还是通过ActivityStackSupervisor的realStartActivityLocked,启动应用进程的首个Activity,那么再往下看,就是一般Activity的启动流程了,realStartActivityLocked仍然比较长,取我们关心的逻辑:

// 创建一个Activity启动的事务,ClientTransaction是一个实现了Parcelable接口的类
// 即该事务对象可以跨进程传递
final ClientTransaction clientTransaction = ClientTransaction.obtain(
	proc.getThread(), r.appToken);
final DisplayContent dc = r.getDisplay().mDisplayContent;
// 往事务中添加一个LaunchActivityItem,代表事务的Callback,后面会执行Callback中的逻辑
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),...));
// ...
// 调度事务,
mService.getLifecycleManager().scheduleTransaction(clientTransaction);

先来看下事务是怎样获取的:

public static ClientTransaction obtain(IApplicationThread client, IBinder activityToken) {
	// 先从对象池中找,找不到就创建
  ClientTransaction instance = ObjectPool.obtain(ClientTransaction.class);
	if (instance == null) {
		instance = new ClientTransaction();
	}
  // 将IApplicationThread赋值给事务的mClient字段,
  // 表示这个事务的接收端是哪个进程的ApplicationThread
	instance.mClient = client;
	instance.mActivityToken = activityToken;
	return instance;
}

ClinetLifeCycleManager的调度事务实现如下:

void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
	final IApplicationThread client = transaction.getClient();
	transaction.schedule();
	// ...
}
//transaction.schedule();实现如下,IPC调用到应用进程ApplicationThread的scheduleTransaction
mClient.scheduleTransaction(this);

而ApplicationThread中的scheduleTransaction实现,就是调用ActivityThread的scheduleTransaction方法(AT继承自ClientTransactionHandler,实现在父类中):

void scheduleTransaction(ClientTransaction transaction) {
  // 当事务在客户端进程执行的时候,在执行之前做一个hook callback操作
	transaction.preExecute(this);
	sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}

发送出去的消息最终还是交给H来处理:

final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction);

mTransactionExecutor并不是什么多线程的Executor,不过是对事务有序处理的逻辑封装,其execute如下:

public void execute(ClientTransaction transaction) {
	// ...
  // executeCallbacks中的重点就是执行传入事务的callback的execute方法
  // item.execute(mTransactionHandler, token, mPendingActions);
  // 
	executeCallbacks(transaction);
	executeLifecycleState(transaction);
	mPendingActions.clear();
	// ...
}

而AMS在调用realStartActivityLocked传入事务的callback就是LaunchActivityItem,他的execute如下:

public void execute(ClientTransactionHandler client, IBinder token,
	PendingTransactionActions pendingActions) {
  // 创建一个ActivityClientRecord对象
	ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
                mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
                mPendingResults, mPendingNewIntents, mIsForward,
                mProfilerInfo, client, mAssistToken, mFixedRotationAdjustments);
  // 这里client实际上就是TransactionExecutor中的mTransactionHandler
	client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
}

在ActivityThread中,ActivityThread对象创建的时候就会创建mTransactionExecutor对象,并把this引用传入到TransactionExecutor的构造方法中,所以这里mTransactionHandler正是实现了ClientTransactionHandler接口的ActivityThread对象,在ActivityThread的handleLaunchActivity中:

final Activity a = performLaunchActivity(r, customIntent);

而performLaunchActivity就会去创建对应的Activity对象,关于performLaunchActivity的分析,可以看前两篇Android UI系统工作流程。

Android UI工作流程1 Android UI工作流程2