ActivityThread源码分析

1、问题

Android 11 Launcher启动流程分析说过,Android App进程的入口是“android.app.ActivityThread”,那么:

  1. ActivityThread在Android App中充当一个什么样的角色?
  2. 它是怎么创建Application的?Application的生命周期是怎样的?
  3. 第一个Activity是怎么启动的?

2、ActivityThread#main

Android 11 进程启动分析(一)中可以看到,Android进程创建(fork)之后都会调用入口类的main方法,这与Java语言本身的设定是一致的。所以这里我们从ActivityThread#main入手,看看它都干了些什么。

public static void main(String[] args) {
    
    // 初始化选择性的系统拦截,这里我们不深究
    AndroidOs.install();

    ...

    Looper.prepareMainLooper();

    ...

    ActivityThread thread = new ActivityThread();
    thread.attach(/*system*/false, startSeq);

    if (sMainThreadHandler == null) {
        sMainThreadHandler = thread.getHandler();
    }

    ...

    Looper.loop();

    throw new RuntimeException("Main thread loop unexpectedly exited");
}

这里的操作很简单,就是创建了一个ActivityThread对象并调用它的attach方法,然后进入主线程消息循环。

3、ActivityThread#attach

private void attach(boolean system, long startSeq) {
    sCurrentActivityThread = this;
    mSystemThread = system;
    if (!system) {
        android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                                                UserHandle.myUserId());
        // 这里只是进行了一个赋值操作,没有额外的方法调用
        RuntimeInit.setApplicationObject(mAppThread.asBinder());
        // IActivityManager是一个AIDL接口,实现类是ActivityManagerService
        final IActivityManager mgr = ActivityManager.getService();
        try {
            mgr.attachApplication(mAppThread, startSeq);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
        
        // 添加监听,当使用内存超过最大可用内存3/4的时候,释放一些Activity,避免OOM
        BinderInternal.addGcWatcher(new Runnable() {
            @Override public void run() {
                if (!mSomeActivitiesChanged) {
                    return;
                }
                Runtime runtime = Runtime.getRuntime();
                long dalvikMax = runtime.maxMemory();
                long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
                if (dalvikUsed > ((3*dalvikMax)/4)) {
                    if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
                            + " total=" + (runtime.totalMemory()/1024)
                            + " used=" + (dalvikUsed/1024));
                    mSomeActivitiesChanged = false;
                    try {
                        ActivityTaskManager.getService().releaseSomeActivities(mAppThread);
                    } catch (RemoteException e) {
                        throw e.rethrowFromSystemServer();
                    }
                }
            }
        });
    } else {
        ...
    }

    ...
}

这里对是否是系统进程做了一个判断,我们这里是分析非系统进程,所以只看if分支。if分支做了两件事情:

  1. 调用ActivityManagerService的attachApplication方法,注册ActivityThread
  2. 添加监听,当使用内存超过最大可用内存3/4的时候,释放一些Activity,避免OOM

这里有一个规律,一般系统的IxxxManager AIDL接口,实现类为xxxManagerService,比如IActivityManager -> ActivityManagerService,IActivityTaskManager -> ActivityTaskManagerService,IWindowManager -> WindowManagerService等等。

这里跟进ActivityManagerService的attachApplication方法。需要注意的是这个方法传进去的mAppThread参数是一个ApplicationThread的对象,它在ActivityThread初始化的时候就new了

final ApplicationThread mAppThread = new ApplicationThread();

ApplicationThread实现了IApplicationThread AIDL接口,用于与AMS通信。

4、ActivityManagerService#attachApplication

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);
    }
}

这里做了一个判空,然后调用了attachApplicationLocked方法

private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
            int pid, int callingUid, long startSeq) {

    
    ProcessRecord app;
    
    if (app.isolatedEntryPoint != null) {
        // This is an isolated process which should just call an entry point instead of
        // being bound to an application.
        thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
    } else if (instr2 != null) {
        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.compat, getCommonServicesLocked(app.isolated),
                mCoreSettingsObserver.getCoreSettingsLocked(),
                buildSerial, autofillOptions, contentCaptureOptions,
                app.mDisabledCompatChanges);
    } else {
        thread.bindApplication(processName, appInfo, providerList, null, profilerInfo,
                null, null, null, testMode,
                mBinderTransactionTrackingEnabled, enableTrackAllocation,
                isRestrictedBackupMode || !normalMode, app.isPersistent(),
                new Configuration(app.getWindowProcessController().getConfiguration()),
                app.compat, getCommonServicesLocked(app.isolated),
                mCoreSettingsObserver.getCoreSettingsLocked(),
                buildSerial, autofillOptions, contentCaptureOptions,
                app.mDisabledCompatChanges);
    }
    if (profilerInfo != null) {
        profilerInfo.closeFd();
        profilerInfo = null;
    }

    app.makeActive(thread, mProcessStats);

    mProcessList.updateLruProcessLocked(app, false, null);
    

    boolean badApp = false;
    boolean didSomething = false;

    // See if the top visible activity is waiting to run in this process...
    // 处理栈顶等待运行的Activity
    didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());

    // Find any services that should be running in this process...
    didSomething |= mServices.attachApplicationLocked(app, processName);

    // Check if a next-broadcast receiver is in this process...
    if (!badApp && isPendingBroadcastProcessLocked(pid)) {
        didSomething |= sendPendingBroadcastsLocked(app);
    }

    // Check whether the next backup agent is in this process...
    if (!badApp && backupTarget != null && backupTarget.app == app) {
        
        thread.scheduleCreateBackupAgent(backupTarget.appInfo,
                    compatibilityInfoForPackage(backupTarget.appInfo),
                    backupTarget.backupMode, backupTarget.userId);
    }

    ...

    return true;
}

这里做了一系列检查和处理之后调用了IApplicationThread对象thread的bindApplication接口,然后调用ProcessList.updateLruProcessLocked方法,让ProcessList去管理这个进程,这个在后续Android的进程管理相关文章会讲到。
紧接着,由调用了mAtmInternal.attachApplication方法,通过注释我们可以看到,这会检查栈顶Activity是否等待运行。
接下来是检查服务和广播,以及备份代理(BackupAgent)?

5、ApplicationThread#bindApplication

先看IApplicationThread#bindApplication,我们知道IApplicationThread的实现类就是ApplicationThread,ApplicationThread#bindApplication方法如下:

public final void bindApplication(String processName, ApplicationInfo appInfo,
                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) {
    ...

    AppBindData data = new AppBindData();
    data.processName = processName;
    data.appInfo = ...

    sendMessage(H.BIND_APPLICATION, data);
}

总体来说就是打包了传进来的参数,然后通过Message发给Handler处理。该Message的处理定义在ActivityThread的内部类H中:

H.handleMessage():

public void handleMessage(Message msg) {
    
    switch (msg.what) {
        case BIND_APPLICATION:
            AppBindData data = (AppBindData)msg.obj;
            handleBindApplication(data);
            break;

        case...
}

这里进而调用了ActivityThread的handleBindApplication方法。

private void handleBindApplication(AppBindData data) {
    
    ...

    mInstrumentation = new Instrumentation();
    mInstrumentation.basicInit(this);

    Application app;
    
    ...
    
    // 实例化Application对象!
    app = data.info.makeApplication(data.restrictedBackupMode, null);

    ...

    mInitialApplication = app;

    ...
    
    mInstrumentation.onCreate(data.instrumentationArgs);
    
    mInstrumentation.callApplicationOnCreate(app);
    
    ...
}

这里创建了mInstrumentation和mInitialApplication成员变量。data.info是一个LoadedApk类对象,一起来看看它的makeApplication方法吧。

LoadedApk#makeApplication():

public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
    if (mApplication != null) {
        return mApplication;
    }

    Application app = null;

    String appClass = mApplicationInfo.className;
    if (forceDefaultAppClass || (appClass == null)) {
        appClass = "android.app.Application";
    }

    
    final java.lang.ClassLoader cl = getClassLoader();

    ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
    
    ...

    app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);
    appContext.setOuterContext(app);
    
    mActivityThread.mAllApplications.add(app);
    mApplication = app;

    ...

    return app;
}

这里先创建了Application的Context,然后通过ActivityThread的mInstrumentation成员变量的newApplication方法。

Instrumentation#newApplication(java.lang.ClassLoader, java.lang.String, android.content.Context):

public Application newApplication(ClassLoader cl, String className, Context context)
            throws InstantiationException, IllegalAccessException, 
            ClassNotFoundException {
    Application app = getFactory(context.getPackageName())
            .instantiateApplication(cl, className);
    app.attach(context);
    return app;
}

这里先获取了一个AppComponentFactory对象,然后调用它的instantiateApplication方法,然后调用了Application#attach方法。可以看到Application创建完成后,第一时间被调用的并不是它的onCreate方法。

AppComponentFactory类的注释是

Interface used to control the instantiation of manifest elements

也就是说,它是专门用来实例化manifest里面定义的元素对应组件的工厂类,包括Application和四大组件。我们来看它的instantiateApplication方法:

public @NonNull Application instantiateApplication(@NonNull ClassLoader cl,
            @NonNull String className)
            throws InstantiationException, IllegalAccessException, ClassNotFoundException {
    return (Application) cl.loadClass(className).newInstance();
}

这个很简单,无须多言。接下来我们看看Application第一个被调用的方法Application#attach(Context)

final void attach(Context context) {
    attachBaseContext(context);
    mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}

这里又调用了它的attachBaseContext方法,并给mLoadedApk赋值。Application本身继承自ContextWrapper,关于Context、ContextWrapper和ContextImpl可以参考这篇文章

回到ActivityThread的handleBindApplication方法。

private void handleBindApplication(AppBindData data) {

    ...
    
    // 实例化Application对象!
    app = data.info.makeApplication(data.restrictedBackupMode, null);

    ...

    mInitialApplication = app;

    ...
    
    mInstrumentation.onCreate(data.instrumentationArgs);
    
    // callApplicationOnCreate里调用了Application的onCreate方法
    mInstrumentation.callApplicationOnCreate(app);
    
    ...
}

Application创建完成之后,调用了attach方法,然后才是我们熟悉的onCreate方法。这是因为Context包含了Android为我们封装好的上下文环境,有了它我们才更方便地在onCreate中进行各种操作。

至此,Application的创建和初始化就完成了。

6、ActivityTaskManagerService.LocalService#attachApplication

回到第4节分析ActivityManagerService#attachApplicationLocked方法的时候,看到:

// See if the top visible activity is waiting to run in this process...
didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());

这里就是启动Activity的相关代码了。mAtmInternal是ActivityTaskManagerInternal的实例,实现类为ActivityTaskManagerService.LocalService。来看看ActivityTaskManagerService.LocalService#attachApplication 都干了些什么吧

public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
    synchronized (mGlobalLockWithoutBoost) {
        ...
        mRootWindowContainer.attachApplication(wpc);
        ...
    }
}

跟进RootWindowContainer#attachApplication()

boolean attachApplication(WindowProcessController app) throws RemoteException {
    final String processName = app.mName;
    boolean didSomething = false;
    for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
        final DisplayContent display = getChildAt(displayNdx);
        final ActivityStack stack = display.getFocusedStack();
        if (stack == null) {
            continue;
        }

        mTmpRemoteException = null;
        mTmpBoolean = false; // Set to true if an activity was started.
        final PooledFunction c = PooledLambda.obtainFunction(
                RootWindowContainer::startActivityForAttachedApplicationIfNeeded, this,
                PooledLambda.__(ActivityRecord.class), app, stack.topRunningActivity());
        stack.forAllActivities(c);
        c.recycle();
        if (mTmpRemoteException != null) {
            throw mTmpRemoteException;
        }
        didSomething |= mTmpBoolean;
    }
    if (!didSomething) {
        ensureActivitiesVisible(null, 0, false /* preserve_windows */);
    }
    return didSomething;
}

这里做了一个遍历,获取每个DisplayContent中活跃的任务栈,然后去启动对应的Activity。

跟进RootWindowContainer#startActivityForAttachedApplicationIfNeeded()

private boolean startActivityForAttachedApplicationIfNeeded(ActivityRecord r,
            WindowProcessController app, ActivityRecord top) {
    ...
    if (mStackSupervisor.realStartActivityLocked(r, app, top == r /*andResume*/,
                true /*checkConfig*/)) {
        mTmpBoolean = true;
    }
    ...
}

这里我们如果是启动Launcher或者从Launcher启动App,top == r应为true,也就是andResume参数为true
跟进StackSupervisor#realStartActivityLocked()方法

boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
            boolean andResume, boolean checkConfig) throws RemoteException {

    ...

    // Create activity launch transaction.
    // 创建activity启动事务
    final ClientTransaction clientTransaction = ClientTransaction.obtain(
            proc.getThread(), r.appToken);

    final DisplayContent dc = r.getDisplay().mDisplayContent;
    clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
            System.identityHashCode(r), r.info,
            // TODO: Have this take the merged configuration instead of separate global
            // and override configs.
            mergedConfiguration.getGlobalConfiguration(),
            mergedConfiguration.getOverrideConfiguration(), r.compat,
            r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
            r.getSavedState(), r.getPersistentSavedState(), results, newIntents,
            dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
            r.assistToken, r.createFixedRotationAdjustmentsIfNeeded()));

    // Set desired final state.
    final ActivityLifecycleItem lifecycleItem;
    if (andResume) {
        lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
    } else {
        lifecycleItem = PauseActivityItem.obtain();
    }
    clientTransaction.setLifecycleStateRequest(lifecycleItem);

    // Schedule transaction.
    mService.getLifecycleManager().scheduleTransaction(clientTransaction);

    ...

    return true;
}

可以看到,这里andResume为true的情况下,事务会连续执行LaunchActivityItem和ResumeActivityItem的动作。
LaunchActivityItem和ResumeActivityItem是都是ClientTransactionItem的子类。

根据经验可以看出LaunchActivityItem和ResumeActivityItem等等是对操作Activity不同生命周期的封装,具体操作应该会在子类实现。这里具体操作在execute方法。

先看LaunchActivityItem#execute:

public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
    ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
            mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
            mPendingResults, mPendingNewIntents, mIsForward,
            mProfilerInfo, client, mAssistToken, mFixedRotationAdjustments);
    client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
}

方法很简单,就是调用了ClientTransactionHandler的handleLaunchActivity,而ActivityThread正是继承自ClientTransactionHandler。来看看ActivityThread#handleLaunchActivity:

public Activity handleLaunchActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent) {
    ...

    final Activity a = performLaunchActivity(r, customIntent);

    ...

    return a;
}

这里核心代码也很简单,跟进

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    ...
    ContextImpl appContext = createBaseContextForActivity(r);
    Activity activity = null;
    
    java.lang.ClassLoader cl = appContext.getClassLoader();
    activity = mInstrumentation.newActivity(
            cl, component.getClassName(), r.intent);
    StrictMode.incrementExpectedActivityCount(activity.getClass());
    
    ...
    
    Application app = r.packageInfo.makeApplication(false, mInstrumentation);

    
    if (activity != 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);
        // 没有调用onCreate前,先调用attach
        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);

        ...

        activity.mCalled = false;
        // 执行onCreate方法
        if (r.isPersistable()) {
            mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
        } else {
            mInstrumentation.callActivityOnCreate(activity, r.state);
        }
        ...
    }
    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);
    }

    ...

    return activity;
}

可以看到,这里Activity创建之后也不是第一时间调用onCreate方法,而是先调用attach准备上下文环境。

Instrumentation#callActivityOnCreate(android.app.Activity, android.os.Bundle):

public void callActivityOnCreate(Activity activity, Bundle icicle) {
    prePerformCreate(activity);
    activity.performCreate(icicle);
    postPerformCreate(activity);
}

这里调用了Activty#performCreate,看看它都干了些啥:

final void performCreate(Bundle icicle) {
    performCreate(icicle, null);
}

@UnsupportedAppUsage
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
    dispatchActivityPreCreated(icicle);
    
    ...
    
    if (persistentState != null) {
        onCreate(icicle, persistentState);
    } else {
        onCreate(icicle);
    }

    ...

    dispatchActivityPostCreated(icicle);
}

这里有3个关键调用,onCreate就不必多说了。来看看dispatchActivityPreCreated方法:

private void dispatchActivityPreCreated(@Nullable Bundle savedInstanceState) {
    getApplication().dispatchActivityPreCreated(this, savedInstanceState);
    Object[] callbacks = collectActivityLifecycleCallbacks();
    if (callbacks != null) {
        for (int i = 0; i < callbacks.length; i++) {
            ((Application.ActivityLifecycleCallbacks) callbacks[i]).onActivityPreCreated(this,
                    savedInstanceState);
        }
    }
}

这就是为什么我们可以在Application或者Activity中调用registerActivityLifecycleCallbacks方法来添加Activity声明周期的监听了。

这里分析了Activity的创建流程,resume的流程也是类似,自行查看以下就可以了,这里不啰嗦了。

7、ActivityThread总览

在这里插入图片描述

8、总结

本文开头提出了3个问题,现在总结答案。

  1. ActivityThread在Android App中充当一个什么样的角色?
    ActivityThread是App进程的入口类,它负责主线程消息循环的创建、Application的创建、与AMS通信、调度四大组件的创建和它们的生命周期。

  2. 它是怎么创建Application的?Application的生命周期是怎样的?
    这个问题并没有完全回答,Application的创建是在AMS调度下通过ActicityThread的mInstrumentation反射创建的,在调用onCreate方法之前先调用了attach方法来初始化上下文。至于销毁和低内存等,会在后续的进程管理相关文章继续解答。

  3. 第一个Activity是怎么启动的?
    AMS在调度完Application的创建和绑定之后,检查是否有待启动的,有的化通知ActivityThread进行创建并执行相关的生命周期方法。与Application一样,先调用了attach准备上下文环境,然后才是onCreate。

另外,需要注意的是,可以看出Application是与进程相关的,一个App如果有多个进程,那么Application也会创建多次。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值