AMS和ActivityThread 通信 appToken ApplicationThread等

本文详细解析了Android中Activity的启动流程,从AMS启动Activity、新建ActivityRecord开始,到ActivityThread启动Activity,深入剖析了ActivityRecord、Token、ActivityClientRecord等关键对象的作用,以及Activity与AMS之间的通信机制。

在之前的博客中对应用启动流程都做了分析,这篇博客主要是一个补充的作用,说下ActivityThread和AMS的通信,以及ActivityClientRecord ApplicationThread AppToken等说明。


AMS启动Activity 、新建ActivityRecord

我们还是从一个Activity启动另一个Activity为切入点说起,startActivity最终会调用ActivityStackSupervisor的startActivityLocked函数,会新建一个ActivityRecord对象。

        ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
                intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
                requestCode, componentSpecified, voiceSession != null, this, container, options);

我们先来看看ActivityRecord对象,在构造函数中会新建一个Token对象,作为自己的appToken成员变量。

    ActivityRecord(ActivityManagerService _service, ProcessRecord _caller,
            int _launchedFromUid, String _launchedFromPackage, Intent _intent, String _resolvedType,
            ActivityInfo aInfo, Configuration _configuration,
            ActivityRecord _resultTo, String _resultWho, int _reqCode,
            boolean _componentSpecified, boolean _rootVoiceInteraction,
            ActivityStackSupervisor supervisor,
            ActivityContainer container, Bundle options) {
        service = _service;
        appToken = new Token(this, service);

我们再来看看Token对象是一个Binder服务,但是这个appToken一般只作为一个唯一标识使用。

    static class Token extends IApplicationToken.Stub {
        private final WeakReference<ActivityRecord> weakActivity;
        private final ActivityManagerService mService;

        Token(ActivityRecord activity, ActivityManagerService service) {
            weakActivity = new WeakReference<>(activity);
            mService = service;
        }

继续到ActivityStack的startActivityLocked函数,这个函数主要把ActivityRecord保存在mTaskHistory中的TaskRecord中。后面还会调用mWindowManager.addAppToken在WMS创建AppWindowToken。

    final void startActivityLocked(ActivityRecord r, boolean newTask,
            boolean doResume, boolean keepCurTransition, Bundle options) {
        TaskRecord rTask = r.task;
        final int taskId = rTask.taskId;
        if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)) {
            // Last activity in task had been removed or ActivityManagerService is reusing task.
            // Insert or replace.
            // Might not even be in.
            insertTaskAtTop(rTask, r);
            mWindowManager.moveTaskToTop(taskId);
        }
        TaskRecord task = null;
        if (!newTask) {
            // If starting in an existing task, find where that is...
            boolean startIt = true;
            for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
                task = mTaskHistory.get(taskNdx);
                if (task.getTopActivity() == null) {
                    // All activities in task are finishing.
                    continue;
                }
                if (task == r.task) {
                    // Here it is!  Now, if this is not yet visible to the
                    // user, then just add it without starting; it will
                    // get started when the user navigates back to it.
                    if (!startIt) {
                        if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to task "
                                + task, new RuntimeException("here").fillInStackTrace());
                        task.addActivityToTop(r);
        ......
         mWindowManager.addAppToken(task.mActivities.indexOf(r),
                    r.appToken, r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
                    (r.info.flags & ActivityInfo.FLAG_SHOW_FOR_ALL_USERS) != 0, r.userId,
                    r.info.configChanges, task.voiceSession != null, r.mLaunchTaskBehind);

继续我们到ActivityStack的resumeTopActivityInnerLocked函数,看下面代码,只要相关ActivityThread的app和appThread不为null,说明已经开启过进程然后ActivityThread到AMS了,所以才会保存这个对象。后面我们会分析到。然后调用next.app.thread.scheduleResumeActivity到ActivityThread的scheduleResumeActivity函数。而当进程没有开启,就会调用mStackSupervisor.startSpecificActivityLocked函数开启进程。

        if (next.app != null && next.app.thread != null) {
            if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resume running: " + next);

            // This activity is now becoming visible.
            mWindowManager.setAppVisibility(next.appToken, true);

            // schedule launch ticks to collect information about slow apps.
            next.startLaunchTickingLocked();

            ActivityRecord lastResumedActivity =
                    lastStack == null ? null :lastStack.mResumedActivity;
            ActivityState lastState = next.state;

            mService.updateCpuStats();

            if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to RESUMED: " + next + " (in existing)");
            next.state = ActivityState.RESUMED;
            mResumedActivity = next;
            next.task.touchActiveTime();
            mRecentTasks.addLocked(next.task);
            mService.updateLruProcessLocked(next.app, true, null);
            updateLRUListLocked(next);
            mService.updateOomAdjLocked();

            // Have the window manager re-evaluate the orientation of
            // the screen based on the new activity order.
            boolean notUpdated = true;
            if (mStackSupervisor.isFrontStack(this)) {
                Configuration config = mWindowManager.updateOrientationFromAppTokens(
                        mService.mConfiguration,
                        next.mayFreezeScreenLocked(next.app) ? next.appToken : null);
                if (config != null) {
                    next.frozenBeforeDestroy = true;
                }
                notUpdated = !mService.updateConfigurationLocked(config, next, false, false);
            }

            if (notUpdated) {
                // The configuration update wasn't able to keep the existing
                // instance of the activity, and instead started a new one.
                // We should be all done, but let's just make sure our activity
                // is still at the top and schedule another run if something
                // weird happened.
                ActivityRecord nextNext = topRunningActivityLocked(null);
                if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_STATES,
                        "Activity config changed during resume: " + next
                        + ", new next: " + nextNext);
                if (nextNext != next) {
                    // Do over!
                    mStackSupervisor.scheduleResumeTopActivities();
                }
                if (mStackSupervisor.reportResumedActivityLocked(next)) {
                    mNoAnimActivities.clear();
                    if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
                    return true;
                }
                if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
                return false;
            }

            try {
                // Deliver all pending results.
                ArrayList<ResultInfo> a = next.results;
                if (a != null) {
                    final int N = a.size();
                    if (!next.finishing && N > 0) {
                        if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
                                "Delivering results to " + next + ": " + a);
                        next.app.thread.scheduleSendResult(next.appToken, a);
                    }
                }

                if (next.newIntents != null) {
                    next.app.thread.scheduleNewIntent(next.newIntents, next.appToken);
                }

                EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, next.userId,
                        System.identityHashCode(next), next.task.taskId, next.shortComponentName);

                next.sleeping = false;
                mService.showAskCompatModeDialogLocked(next);
                next.app.pendingUiClean = true;
                next.app.forceProcessStateUpTo(mService.mTopProcessState);
                next.clearOptionsLocked();
                next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState,
                        mService.isNextTransitionForward(), resumeAnimOptions);

                mStackSupervisor.checkReadyForSleepLocked();

                if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Resumed " + next);
            } catch (Exception e) {
                // Whoops, need to restart this activity!
                if (DEBUG_STATES) Slog.v(TAG_STATES, "Resume failed; resetting state to "
                        + lastState + ": " + next);
                next.state = lastState;
                if (lastStack != null) {
                    lastStack.mResumedActivity = lastResumedActivity;
                }
                Slog.i(TAG, "Restarting because process died: " + next);
                if (!next.hasBeenLaunched) {
                    next.hasBeenLaunched = true;
                } else  if (SHOW_APP_STARTING_PREVIEW && lastStack != null &&
                        mStackSupervisor.isFrontStack(lastStack)) {
                    mWindowManager.setAppStartingWindow(
                            next.appToken, next.packageName, next.theme,
                            mService.compatibilityInfoForPackageLocked(next.info.applicationInfo),
                            next.nonLocalizedLabel, next.labelRes, next.icon, next.logo,
                            next.windowFlags, null, true);
                }
                mStackSupervisor.startSpecificActivityLocked(next, true, false);
                if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
                return true;
            }

            // From this point on, if something goes wrong there is no way
            // to recover the activity.
            try {
                next.visible = true;
                completeResumeLocked(next);
            } catch (Exception e) {
                // If any exception gets thrown, toss away this
                // activity and try the next one.
                Slog.w(TAG, "Exception thrown during resume of " + next, e);
                requestFinishActivityLocked(next.appToken, Activity.RESULT_CANCELED, null,
                        "resume-exception", true);
                if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
                return true;
            }
            next.stopped = false;

        } else {
            EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, "ActivityStack resumeTopActivityInnerLock startSpecificActivityLocked fork process");
            // Whoops, need to restart this activity!
            if (!next.hasBeenLaunched) {
                next.hasBeenLaunched = true;
            } else {
                if (SHOW_APP_STARTING_PREVIEW) {
                    mWindowManager.setAppStartingWindow(
                            next.appToken, next.packageName, next.theme,
                            mService.compatibilityInfoForPackageLocked(
                                    next.info.applicationInfo),
                            next.nonLocalizedLabel,
                            next.labelRes, next.icon, next.logo, next.windowFlags,
                            null, true);
                }
                if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
            }
            if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
            mStackSupervisor.startSpecificActivityLocked(next, true, true);
        }

我们来看下ActivityStackSupervisor.startSpecificActivityLocked函数,如果进程没有会调用AMS的startProcessLocked函数,在这个函数会新建一个ProcessRecord对象保存进程信息,然后调用Process类的start来启动进程。

    void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);

        r.task.stack.setLaunchTime(r);

        if (app != null && app.thread != null) {
            try {
                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                        || !"android".equals(r.info.packageName)) {
                    // Don't add this if it is a platform component that is marked
                    // to run in multiple processes, because this is actually
                    // part of the framework so doesn't make sense to track as a
                    // separate apk in the process.
                    app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                            mService.mProcessStats);
                }
                realStartActivityLocked(r, app, 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.
        }

        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }


应用进程启动、 ActivityThread新建

进程开启后就直接到ActivityThread的main方法,主要是下面代码我们来看下,新建了一个ActivityThread,然后调用其attach方法,参数为false,代表是应用进程。

        ActivityThread thread = new ActivityThread();
        thread.attach(false);

在attach函数中主要是调用了AMS的attachApplication,把名mAppthread传过去了。

    private void attach(boolean system) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {
            ViewRootImpl.addFirstDrawHandler(new Runnable() {
                @Override
                public void run() {
                    ensureJitEnabled();
                }
            });
            android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                                                    UserHandle.myUserId());
            RuntimeInit.setApplicationObject(mAppThread.asBinder());
            final IActivityManager mgr = ActivityManagerNative.getDefault();
            try {
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                // Ignore
            }


ApplicationThread类

mAppThread在ActivityThread构造的时候就创建了,我们来看下这个类:

final ApplicationThread mAppThread = new ApplicationThread();

其继承与ApplicationThreadNative类,我们来看下这个父类:

private class ApplicationThread extends ApplicationThreadNative

ApplicationThreadNative类就是典型的Binder服务类,只是这里直接写的而没用aidl那种机制。

public abstract class ApplicationThreadNative extends Binder
        implements IApplicationThread {
    /**
     * Cast a Binder object into an application thread interface, generating
     * a proxy if needed.
     */
    static public IApplicationThread asInterface(IBinder obj) {
        if (obj == null) {
            return null;
        }
        IApplicationThread in =
            (IApplicationThread)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }
        
        return new ApplicationThreadProxy(obj);
    }
    
    public ApplicationThreadNative() {
        attachInterface(this, descriptor);
    }
    
    @Override
    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException {
        switch (code) {
        case SCHEDULE_PAUSE_ACTIVITY_TRANSACTION:
        {
            data.enforceInterface(IApplicationThread.descriptor);
            IBinder b = data.readStrongBinder();
            boolean finished = data.readInt() != 0;
            boolean userLeaving = data.readInt() != 0;
            int configChanges = data.readInt();
            boolean dontReport = data.readInt() != 0;
            schedulePauseActivity(b, finished, userLeaving, configChanges, dontReport);
            return true;
        }

        ......
        }

        return super.onTransact(code, data, reply, flags);
    }

    public IBinder asBinder()
    {
        return this;
    }
}

class ApplicationThreadProxy implements IApplicationThread {
    private final IBinder mRemote;
    
    public ApplicationThreadProxy(IBinder remote) {
        mRemote = remote;
    }
    
    public final IBinder asBinder() {
        return mRemote;
    }
    
    public final void schedulePauseActivity(IBinder token, boolean finished,
            boolean userLeaving, int configChanges, boolean dontReport) throws RemoteException {
        Parcel data = Parcel.obtain();
        data.writeInterfaceToken(IApplicationThread.descriptor);
        data.writeStrongBinder(token);
        data.writeInt(finished ? 1 : 0);
        data.writeInt(userLeaving ? 1 :0);
        data.writeInt(configChanges);
        data.writeInt(dontReport ? 1 : 0);
        mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null,
                IBinder.FLAG_ONEWAY);
        data.recycle();
    }
而在ApplicationThread 类中只是对各个接口的实现。

    private class ApplicationThread extends ApplicationThreadNative {
        private static final String DB_INFO_FORMAT = "  %8s %8s %14s %14s  %s";

        private int mLastProcessState = -1;

        private void updatePendingConfiguration(Configuration config) {
            synchronized (mResourcesManager) {
                if (mPendingConfiguration == null ||
                        mPendingConfiguration.isOtherSeqNewer(config)) {
                    mPendingConfiguration = config;
                }
            }
        }

        public final void schedulePauseActivity(IBinder token, boolean finished,
                boolean userLeaving, int configChanges, boolean dontReport) {
            sendMessage(
                    finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
                    token,
                    (userLeaving ? 1 : 0) | (dontReport ? 2 : 0),
                    configChanges);
        }


AMS的attachApplication方法

我们先来看AMS的attachApplication中有下面这么一句,这句话就把IAPPlicationThread保存在ProcessRecord的thread中。这里app对象是ProcessRecord对象。

        app.makeActive(thread, mProcessStats);

我们继续看AMS的attachApplication函数中先会利用刚才从ActivityThread传过来的IApplicationThread的Binder服务反调bindApplication接口,来完成应用进程的一些初始化。

            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
                    isRestrictedBackupMode || !normalMode, app.persistent,
                    new Configuration(mConfiguration), app.compat,
                    getCommonServicesLocked(app.isolated),
                    mCoreSettingsObserver.getCoreSettingsLocked());

随后会继续调用mStackSupervisor.attachApplicationLocked函数,继续开启Activity

        if (normalMode) {
            try {
                if (mStackSupervisor.attachApplicationLocked(app)) {
                    didSomething = true;
                }
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
        }

在ActivityStackSupervisor中会得到当前启动的ActivityRecord,然后调用realStartActivityLocked函数继续启动Activity。

    boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
        final String processName = app.processName;
        boolean didSomething = false;
        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                final ActivityStack stack = stacks.get(stackNdx);
                if (!isFrontStack(stack)) {
                    continue;
                }
                ActivityRecord hr = stack.topRunningActivityLocked(null);
                if (hr != null) {
                    if (hr.app == null && app.uid == hr.info.applicationInfo.uid
                            && processName.equals(hr.processName)) {
                        try {
                            if (realStartActivityLocked(hr, app, true, true)) {
                                didSomething = true;
                            }
                        } catch (RemoteException e) {
                            Slog.w(TAG, "Exception in new application when starting activity "
                                  + hr.intent.getComponent().flattenToShortString(), e);
                            throw e;
                        }
                    }
                }
            }
        }

而在realStartActivityLocked,会把ProcessRecord对象保存在ActivityRecord中的app中。所以在AMS启动Activity时候,看这个Activity的进程有没有启动就是看ActivityRecord的app和app.thread是否为null。而这个函数最后会通过app.thread也就是IAPplicationThread调用ThreadActivity的scheduleLaunchActivity函数。

    final boolean realStartActivityLocked(ActivityRecord r,
            ProcessRecord app, boolean andResume, boolean checkConfig)
            throws RemoteException {

        if (andResume) {
            r.startFreezingScreenLocked(app, 0);
            mWindowManager.setAppVisibility(r.appToken, true);

            // schedule launch ticks to collect information about slow apps.
            r.startLaunchTickingLocked();
        }

        // Have the window manager re-evaluate the orientation of
        // the screen based on the new activity order.  Note that
        // as a result of this, it can call back into the activity
        // manager with a new orientation.  We don't care about that,
        // because the activity is not currently running so we are
        // just restarting it anyway.
        if (checkConfig) {
            Configuration config = mWindowManager.updateOrientationFromAppTokens(
                    mService.mConfiguration,
                    r.mayFreezeScreenLocked(app) ? r.appToken : null);
            mService.updateConfigurationLocked(config, r, false, false);
        }

        r.app = app;

ActivityThread 启动Activity

而我们再来看ActivityThread的scheduleLaunchActivity函数,会创建一个ActivityClientRecord 对象,注意这里的token就是AMS的ActivityRecord中的appToken对象,来保证每个Activity的唯一性。继续发送消息。

        @Override
        public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
                CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
                int procState, Bundle state, PersistableBundle persistentState,
                List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
                boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {

            updateProcessState(procState, false);

            ActivityClientRecord r = new ActivityClientRecord();

            r.token = token;
            r.ident = ident;
            r.intent = intent;
            r.referrer = referrer;
            r.voiceInteractor = voiceInteractor;
            r.activityInfo = info;
            r.compatInfo = compatInfo;
            r.state = state;
            r.persistentState = persistentState;

            r.pendingResults = pendingResults;
            r.pendingIntents = pendingNewIntents;

            r.startsNotResumed = notResumed;
            r.isForward = isForward;

            r.profilerInfo = profilerInfo;

            r.overrideConfig = overrideConfig;
            updatePendingConfiguration(curConfig);

            sendMessage(H.LAUNCH_ACTIVITY, r);
        }

然后在handleLaunchActivity函数中调用performLaunchActivity函数,在performLaunchActivity函数中完成新建Activity,调用Activity的attach方法,以及将ActivityClientRecord放入mActivities中。

    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ......

        Activity activity = null;
        try {
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            activity = mInstrumentation.newActivity(//新建Activity
                    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) {
                Context appContext = createBaseContextForActivity(r, activity);
                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
                Configuration config = new Configuration(mCompatConfiguration);
                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
                        + r.activityInfo.name + " with config " + config);
                activity.attach(appContext, this, getInstrumentation(), r.token,//调用Activity的attach方法
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor);

                if (customIntent != null) {
                    activity.mIntent = customIntent;
                }
                r.lastNonConfigurationInstances = null;
                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);//调用Activity的onCreate方法
                }
            ......

            mActivities.put(r.token, r);//放入mActivities中

        }




<think>我们正在讨论Android系统中的两个核心概念:ActivityRecordActivityThread。根据提供的引用内容相关知识,我将详细解释它们的区别各自的作用。首先,从引用[3]中我们知道,ActivityRecord是ATMS(ActivityTaskManagerService)用来记录每个Activity的信息的数据结构。它包含Activity的状态、所属进程等详细信息。而ActivityThread(引用[4])是应用程序的主线程,负责管理应用程序组件的生命周期消息循环。###ActivityRecord-**定义**:ActivityRecord是系统服务端(ATMS)中代表一个Activity实例的数据结构。每个启动的Activity都会对应一个ActivityRecord对象。-**作用**:-记录Activity的详细信息,如包名、类名、启动模式、任务栈(Task)信息等。-管理Activity的生命周期状态(如created,started,resumed等)。-维护Activity在任务栈(Task)中的位置(引用[1][3]提到,ActivityRecord被组织在Task中,Task具有栈的特性)。-**存在位置**:ActivityRecord存在于系统服务端(system_server进程)中,由ATMS管理。###ActivityThread-**定义**:ActivityThread是应用程序进程的主线程,也是应用程序的入口点。它负责执行应用程序代码,并管理应用程序组件的生命周期。-**作用**:-**管理应用程序组件的生命周期**(引用[4]):通过内部类ApplicationThread(继承自IApplicationThread.Stub,是一个Binder对象)与AMS(或ATMS)通信,接收系统服务发来的生命周期回调指令,然后执行相应的生命周期方法(如Activity的onCreate、onStart等)。-**维护消息循环**(引用[4]):包含一个Looper,处理主线程的消息队列,用于分发事件(如用户输入事件、生命周期回调等)。-**处理系统回调**(引用[4]):通过ApplicationThread接收系统服务发来的回调,然后转发给主线程处理。-**存在位置**:ActivityThread运行在应用程序进程中。###两者区别1.**所在进程不**:-ActivityRecord位于系统服务进程(system_server)。-ActivityThread位于应用程序进程。2.**职责不**:-ActivityRecord是服务端对Activity的抽象,用于记录Activity的状态任务栈信息,以便系统服务进行管理(如任务栈管理、生命周期调度)。-ActivityThread是应用程序进程的主线程,负责执行Activity的生命周期方法其他应用代码。3.**交互方式**:-当需要启动一个Activity时,ATMS(服务端)会创建或复用ActivityRecord,然后通过Binder调用应用程序进程的ApplicationThreadActivityThread的内部类)来通知客户端执行相应的生命周期方法。-例如,当ATMS决定启动一个Activity时,它会通过IApplicationThread.scheduleLaunchActivity()方法通知应用程序进程。然后ActivityThread会调用handleLaunchActivity()方法,最终执行Activity的onCreate()、onStart()等方法(引用[2]展示了handleResumeActivityperformRestartActivity的调用流程)。###交互流程示例(启动Activity)1.**服务端(ATMS)**:-创建ActivityRecord,并确定其任务栈(Task)。-通过IApplicationThread接口(即ApplicationThread的Binder代理)向客户端发送消息(如scheduleLaunchActivity)。2.**客户端(应用程序进程)**:-ApplicationThread收到scheduleLaunchActivity调用,通过Handler将消息发送到主线程(ActivityThread)。-ActivityThread在handleLaunchActivity()方法中:-创建Activity实例(通过反射)。-调用Activity的onCreate()、onStart()等方法。-最后在handleResumeActivity()中调用onResume()(引用[2])。###总结|**特性**|**ActivityRecord**|**ActivityThread**||------------------|----------------------------------------------------|----------------------------------------------------||所在进程|系统服务进程(system_server)|应用程序进程||主要职责|记录Activity状态,管理任务栈位置|执行应用代码,管理组件生命周期,处理主线程消息循环||生命周期管理角色|服务端调度|客户端执行||数据结构/类|数据结构(服务端)|类(应用程序主线程)||交互方式|通过Binder(IApplicationThread)通知ActivityThread|通过Handler处理来自ApplicationThread的消息|>**关键点**:ActivityRecord是服务端对Activity的表示,而ActivityThread是客户端执行实际代码的线程。两者通过Binder机制(ApplicationThread)协完成Activity的生命周期管理[^1][^3][^4]。---§§相关问题§§1.ActivityRecord与ActivityClientRecord有何关联?2.ApplicationThread如何将系统服务端的调用转发给ActivityThread?3.ATMS如何通过ActivityRecord管理Activity的生命周期状态?4.在应用程序进程销毁重建时,ActivityThread如何恢复ActivityRecord信息?</think>### Android ActivityRecord 与 ActivityThread 的区别及各自作用 #### **1. ActivityRecord(系统服务端组件)** **定位**:系统服务端(ATMS)管理 Activity 的核心数据结构,存在于 `system_server` 进程。 **核心作用**: - **记录 Activity 元数据** 存储 Activity 的包名、类名、启动模式(如 `singleTask`)、任务栈(Task)归属等信息[^1][^3]。 - **管理任务栈关系** 通过 `Task` 容器组织多个 ActivityRecord,实现栈式管理(先进后出)[^3]: ```java // 伪代码:Task 中的 ActivityRecord 链表 class Task { List<ActivityRecord> mActivities; // 按启动顺序存储 void addActivity(ActivityRecord r) { mActivities.add(r); } } ``` - **维护生命周期状态** 跟踪 Activity 的状态机(如 `RESUMED`/`PAUSED`),供 ATMS 决策栈操作[^1][^3]。 - **跨进程通信中介** 作为 Binder 通信的标识,ATMS 通过 ActivityRecord 定位目标 Activity[^3]。 > **本质**:系统服务端对 Activity 的**抽象描述**,不包含业务逻辑。 --- #### **2. ActivityThread(应用进程主线程)** **定位**:应用程序的主线程入口,存在于**每个应用进程**。 **核心作用**: - **执行组件生命周期** 直接调用 Activity 的生命周期方法[^2][^4]: ```java // Android 14 源码示例 public void handleResumeActivity(...) { performRestartActivity(r); // → r.activity.performStart() r.activity.performResume(); // 执行 onResume() } ``` - **维护消息循环** 通过 `Looper` 处理事件(如点击事件、生命周期回调)[^4]: ```mermaid graph LR A[系统回调] --> B(ApplicationThread) B --> C[Handler] C --> D[ActivityThread主线程] D --> E[执行生命周期方法] ``` - **桥接系统服务** 通过内部类 `ApplicationThread`(继承 `IApplicationThread.Stub`)接收 ATMS 指令[^4][^5]: ```java // Binder 通信接口 class ApplicationThread extends IApplicationThread.Stub { void scheduleLaunchActivity(...) { /* 转发启动指令 */ } void scheduleResumeActivity(...) { /* 转发恢复指令 */ } } ``` > **本质**:应用进程的**执行引擎**,负责运行实际业务代码。 --- ### 关键区别总结 | **维度** | **ActivityRecord** | **ActivityThread** | |------------------|---------------------------------------------|-----------------------------------------| | **所在进程** | 系统服务进程 (`system_server`) | 应用进程 (每个应用独立) | | **职责** | 记录元数据、管理任务栈关系 | 执行生命周期方法、处理应用逻辑 | | **数据/行为** | 数据结构(无代码逻辑) | 线程(包含消息循环代码执行能力) | | **生命周期角色** | 状态记录者 | 状态执行者 | | **交互方式** | 通过 Binder 标识 Activity | 通过 Binder 接收系统指令 | > **协流程示例**: > 当 ATMS 决定启动 Activity 时: > 1. 创建 `ActivityRecord` 并关联 Task > 2. 通过 `ApplicationThread` 通知目标应用的 `ActivityThread` > 3. `ActivityThread` 执行 `onCreate()` → `onStart()` → `onResume()`[^2][^4] ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值