美文网首页
Launcher点击图标启动App流程分析(基于Android

Launcher点击图标启动App流程分析(基于Android

作者: GameProgramer | 来源:发表于2021-03-25 10:55 被阅读0次

    压箱底了好几年,一直忘了发布 😂,今天发布一下。

    在安卓开发中,四大组件-Activity,Servie,Broadcast receiver以及contentprovider是一个应用的主要组成部分。在应用中每一个界面都对应一个activity,而各个界面之间的跳转对应着activity之间的切换。那么activity是怎么启动的呢?

    activity的启动场景主要分两种:Launcher界面点击应用图标启动activity;在应用程序的activity中启动另一个activity。

    本文主要分析第一种启动场景-在Launcher界面启动activity的流程,在应用程序的activity中启动另一个activity的场景将在后面的文章中分析。流程分析的代码是基于android N的。

    下面分析在Launcher界面点击应用图标启动应用主activity的流程。

    首先将启动流程大致分为四大步:

    第一步:Launcher进程通知AMS自己想要启动一个应用的主activity,其中Launcher和AMS的通信使用了跨进程技术,流程图如下,其中ActivityManagerProxy是AMS的远程接口。

    第二步:AMS收到启动activity的请求后会调整一下自身的状态(为后面启动新的activity做准备)并要求Launcher当前栈顶的activity进入pause状态,流程图如下,其中ApplicationThreadProxy是ApplicationThread的远程接口。

    第三步:Launcher pause完当前栈顶activity后通知AMS可以开始启动新activity了,因为这是一个待启动进程的主activity,因此AMS要先启动一个新的进程然后才能在新的进程中完成启动主activity的任务,其中Process.start接口会加载一个ActivityThread类并调用其main方法启动一个新的进程,此时Launcher基本完成任务,后面主要是新进程和AMS的交互来完成activity的真正启动。

    第四步:新的进程启动后会通过调用attachApplication与AMS建立关联,AMS也会将该进程相关的一些信息保存起来以便于后期管理,准备就绪后AMS会通过ApplicationThread的远程接口ApplicationThreadProxy来调用scheduleLaunchActivity通知新进程开始真正启动activity的工作了,activity的onCreate和onResume函数都是在ActivityThread的handleLaunchActivity中完成的。

    至此,在新的进程中启动activity的流程走完了,其中涉及到了多次进程通信。

    下面是详细的代码流程:

    1.Launcher.startActivity
    Launcher的源代码工程在packages/apps/Launcher2目录下,负责启动其它应用程序的源代码实现在src/com/android/launcher2/Launcher.java文件中:

    public final class Launcher extends Activity
            implements View.OnClickListener, OnLongClickListener,LauncherModel.Callbacks,
            View.OnTouchListener {
        ......
        public void onClick(View v) {
                // Make sure that rogue clicks don't get through while allapps is launching, or after the
                // view has detached (it's possible for this to happen if the view is removed mid touch).
                if (v.getWindowToken() == null) {
                    return;
                }
    
                if (!mWorkspace.isFinishedSwitchingState()) {
                    return;
                }
    
               Object tag = v.getTag();
                if (tag instanceof ShortcutInfo) {
                    // Open shortcut
                   final Intent intent = ((ShortcutInfo) tag).intent;
                   int[] pos = new int[2];
                    v.getLocationOnScreen(pos);
                    intent.setSourceBounds(new Rect(pos[0], pos[1],
                           pos[0] + v.getWidth(), pos[1] + v.getHeight()));
    
                    boolean success = startActivitySafely(v, intent, tag);
    
                   if (success && v instanceof BubbleTextView) {
                        mWaitingForResume = (BubbleTextView) v;
                       mWaitingForResume.setStayPressed(true);
                    }
               } else if (tag instanceof FolderInfo) {
                   ......
               } else if (v == mAllAppsButton) {
                   ......
               }
        } 
    
        boolean startActivitySafely(View v, Intent intent, Object tag) {
            boolean success = false;
            try {
                success = startActivity(v, intent, tag);
            } catch (ActivityNotFoundException e) {
                ......
            }
            return success;
        }
    
        boolean startActivity(View v, Intent intent, Object tag) {
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    
            try {
                // Only launch using the new animation if the shortcut has not opted out (this is a
               // private contract between launcher and may be ignored in the future).
                boolean useLaunchAnimation = (v != null) &&
                        !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);
                UserHandle user = (UserHandle) intent.getParcelableExtra(ApplicationInfo.EXTRA_PROFILE);
                LauncherApps launcherApps = (LauncherApps)
                        this.getSystemService(Context.LAUNCHER_APPS_SERVICE);
                if (useLaunchAnimation) {
                    ActivityOptions opts = ActivityOptions.makeScaleUpAnimation(v, 0, 0,
                            v.getMeasuredWidth(), v.getMeasuredHeight());
                    if (user == null || user.equals(android.os.Process.myUserHandle())) {
                        // Could be launching some bookkeeping activity
                        startActivity(intent, opts.toBundle());
                    } else {
                        launcherApps.startMainActivity(intent.getComponent(), user,
                                intent.getSourceBounds(),
                               opts.toBundle());
                   }
                } else {
                    if (user == null || user.equals(android.os.Process.myUserHandle())) {
                        startActivity(intent);
                    } else {
                        launcherApps.startMainActivity(intent.getComponent(), user,
                                intent.getSourceBounds(), null);
                    }
                }
                return true;
            } catch (SecurityException e) {
                ......
            }
            return false;
        }
    

    可以看到,点击应用图标后会调到Launcher的startActivity(View v, Intent intent, Object tag)方法,在该方法中为Intent添加了一个FLAG-Intent.FLAG_ACTIVITY_NEW_TASK,该FLAG表示要在一个新的Task中启动这个Activity,注意,Task是Android系统中的概念,它不同于进程Process的概念。简单地说,一个Task是一系列Activity的集合,这个集合是以堆栈的形式来组织的,遵循后进先出的原则。

    2.Activity.startActivity
    因为Launcher继承于Activity,因此上面的startActivity最终都会调到Activity.startActivity,它实现在frameworks/base/core/java/android/app/Activity.java文件中:

    public class Activity extends ContextThemeWrapper
            implements LayoutInflater.Factory2,
            Window.Callback, KeyEvent.Callback,
            OnCreateContextMenuListener, ComponentCallbacks2,
            Window.OnWindowDismissedCallback, WindowControllerCallback {
        ......
        @Override
        public void startActivity(Intent intent) {
            this.startActivity(intent, null);
        }
    
        @Override
        public void startActivity(Intent intent, @Nullable Bundle options) {
            if (options != null) {
                startActivityForResult(intent, -1, options);
            } else {
                // Note we want to go through this call for compatibility with
                // applications that may have overridden the method.
                startActivityForResult(intent, -1);
            }
        }
    
        public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
                @Nullable Bundle options) {
            if (mParent == null) {
                Instrumentation.ActivityResult ar =
                    mInstrumentation.execStartActivity(
                        this, mMainThread.getApplicationThread(), mToken, this,
                        intent, requestCode, options);
                if (ar != null) {
                    mMainThread.sendActivityResult(
                        mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                        ar.getResultData());
                }
                if (requestCode >= 0) {
                    // If this start is requesting a result, we can avoid making
                    // the activity visible until the result is received.  Setting
                    // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
                    // activity hidden during this time, to avoid flickering.
                    // This can only be done when a result is requested because
                    // that guarantees we will get information back when the
                    // activity is finished, no matter what happens to it.
                    mStartedActivity = true;
                }
    
                cancelInputsAndStartExitTransition(options);
                // TODO Consider clearing/flushing other event sources and events for child windows.
            } else {
                ....
            }
        }
    }
    

    上面的方法startActivity(Intent intent, @Nullable Bundle options)中的if和else最后都会调到startActivityForResult(@RequiresPermission Intent intent, int requestCode,
    @Nullable Bundle options),然后又调到mInstrumentation.execStartActivity;这里的mInstrumentation是Activity类的成员变量,它的类型是Intrumentation,定义在frameworks/base/core/java/android/app/Instrumentation.java文件中,它用来监控应用程序和系统的交互。
    这里的mMainThread也是Activity类的成员变量,它的类型是ActivityThread,它代表的是应用程序的主线程,通过mMainThread.getApplicationThread获得它里面的ApplicationThread成员变量,它是一个Binder对象,后面我们会看到,ActivityManagerService会使用它来和ActivityThread来进行进程间通信。这里我们需注意的是,这里的mMainThread代表的是Launcher应用程序运行的进程。

    3.Instrumentation.execStartActivity
    这个函数定义在frameworks/base/core/java/android/app/Instrumentation.java文件中:

    public class Instrumentation {
        ......
        public ActivityResult execStartActivity(
                Context who, IBinder contextThread, IBinder token, Activity target,
                Intent intent, int requestCode, Bundle options) {
            IApplicationThread whoThread = (IApplicationThread) contextThread;
            Uri referrer = target != null ? target.onProvideReferrer() : null;
            if (referrer != null) {
                intent.putExtra(Intent.EXTRA_REFERRER, referrer);
            }
            if (mActivityMonitors != null) {
                ......
            }
            try {
                intent.migrateExtraStreamToClipData();
                intent.prepareToLeaveProcess(who);
                int result = ActivityManagerNative.getDefault()
                    .startActivity(whoThread, who.getBasePackageName(), intent,
                            intent.resolveTypeIfNeeded(who.getContentResolver()),
                            token, target != null ? target.mEmbeddedID : null,
                            requestCode, 0, null, options);
                checkStartActivityResult(result, intent);
            } catch (RemoteException e) {
                throw new RuntimeException("Failure from system", e);
            }
            return null;
        }
    
    }
    

    这里的ActivityManagerNative.getDefault返回ActivityManagerService的远程接口,即ActivityManagerProxy接口。

    4.ActivityManagerProxy.startActivity
    该函数定义在frameworks/base/core/java/android/app/ActivityManagerNative.java文件中:

    abstract class ActivityManagerProxy implements IActivityManager
    {
        ......
    
        public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
                String resolvedType, IBinder resultTo, String resultWho, int requestCode,
                int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
            Parcel data = Parcel.obtain();
            Parcel reply = Parcel.obtain();
            data.writeInterfaceToken(IActivityManager.descriptor);
            data.writeStrongBinder(caller != null ? caller.asBinder() : null);
            data.writeString(callingPackage);
            intent.writeToParcel(data, 0);
            data.writeString(resolvedType);
            data.writeStrongBinder(resultTo);
            data.writeString(resultWho);
            data.writeInt(requestCode);
            data.writeInt(startFlags);
            if (profilerInfo != null) {
                data.writeInt(1);
                profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
            } else {
                data.writeInt(0);
            }
            if (options != null) {
                data.writeInt(1);
                options.writeToParcel(data, 0);
            } else {
                data.writeInt(0);
            }
            mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
            reply.readException();
            int result = reply.readInt();
            reply.recycle();
            data.recycle();
            return result;
        }
    
    }
    

    主要关注下参数caller为ApplicationThread类型的Binder实体,后面通过Binder驱动程序进入到ActivityManagerService的startActivity函数。

    5.ActivityManagerService.startActivity该函数定义在定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

    public class ActivityManagerService extends ActivityManagerNativeEx
            implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
        ......
        @Override
        public int startActivity(IApplicationThread caller, String callingPackage,
                Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
                int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
            return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                    resultWho, requestCode, startFlags, profilerInfo, bOptions,
                    UserHandle.getCallingUserId());
        }
    
        @Override
        public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
                Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
                int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
            enforceNotIsolatedCaller("startActivity");
            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
                    userId, false, ALLOW_FULL_ONLY, "startActivity", null);
            // TODO: Switch to user app stacks here.
            return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
                    profilerInfo, null, null, bOptions, false, userId, null, null);
        }
    

    这里调到了mActivityStarter.startActivityMayWait,其中mActivityStarter是ActivityStarter类型的

    6.ActivityStarter.startActivityMayWait,该函数定义在frameworks/base/services/java/com/android/server/am/ActivityStarter.java文件中:

    class ActivityStarter {
        ......
            final int startActivityMayWait(IApplicationThread caller, int callingUid,
                String callingPackage, Intent intent, String resolvedType,
                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                IBinder resultTo, String resultWho, int requestCode, int startFlags,
                ProfilerInfo profilerInfo, IActivityManager.WaitResult outResult, Configuration config,
                Bundle bOptions, boolean ignoreTargetSecurity, int userId,
                IActivityContainer iContainer, TaskRecord inTask) {
                ......
    
                final ActivityRecord[] outRecord = new ActivityRecord[1];
                int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
                        aInfo, rInfo, voiceSession, voiceInteractor,
                        resultTo, resultWho, requestCode, callingPid,
                        callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                        options, ignoreTargetSecurity, componentSpecified, outRecord, container,
                        inTask);
    
                ......
    
                final ActivityRecord launchedActivity = mReusedActivity != null
                        ? mReusedActivity : outRecord[0];
                mSupervisor.mActivityMetricsLogger.notifyActivityLaunched(res, launchedActivity);
                return res;
            }
    
        final int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
                String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
                String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
                ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
                ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
                TaskRecord inTask) {
                int err = ActivityManager.START_SUCCESS;
                ......
                try {
                    mService.mWindowManager.deferSurfaceLayout();
                    err = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
                            true, options, inTask);
                    Slog.d(TAG,"startActivityUncheckedLocked result : " + err);
                } finally {
                    mService.mWindowManager.continueSurfaceLayout();
                }
                postStartActivityUncheckedProcessing(r, err, stack.mStackId, mSourceRecord, mTargetStack);
            return err;
        }
    
        private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {
           ......
           if (mDoResume) {
                if (!mLaunchTaskBehind) {
                    // TODO(b/26381750): Remove this code after verification that all the decision
                    // points above moved targetStack to the front which will also set the focus
                    // activity.
                    mService.setFocusedActivityLocked(mStartActivity, "startedActivity");
                }
                final ActivityRecord topTaskActivity = mStartActivity.task.topRunningActivityLocked();
                if (!mTargetStack.isFocusable()
                        || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                        && mStartActivity != topTaskActivity)) {
                    // If the activity is not focusable, we can't resume it, but still would like to
                    // make sure it becomes visible as it starts (this will also trigger entry
                    // animation). An example of this are PIP activities.
                    // Also, we don't want to resume activities in a task that currently has an overlay
                    // as the starting activity just needs to be in the visible paused state until the
                    // over is removed.
                    mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
                    // Go ahead and tell window manager to execute app transition for this activity
                    // since the app transition will not be triggered through the resume channel.
                    mWindowManager.executeAppTransition();
                } else {
                    mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,mOptions);
                }
            } else {
                mTargetStack.addRecentActivityLocked(mStartActivity);
            }
            mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);
    
            mSupervisor.handleNonResizableTaskIfNeeded(
                    mStartActivity.task, preferredLaunchStackId, mTargetStack.mStackId);
    
        }
    }
    

    ActivityStarter最后调到ActivityStackSupervisor中。

    7.ActivityStackSupervisor.resumeFocusedStackTopActivityLocked,该函数定义在
    frameworks/base/services/java/com/android/server/am/ActivityStackSupervisor.java文件中:

    public final class ActivityStackSupervisor implements DisplayListener {
        ......
        boolean resumeFocusedStackTopActivityLocked(
                ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
            if (targetStack != null && isFocusedStack(targetStack)) {
                return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
            }
            final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
            if (r == null || r.state != RESUMED) {
                mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
            }
            return false;
        }
    

    ActivityStackSupervisor又调用ActivityStack的resumeTopActivityUncheckedLocked函数。

    8.ActivityStack.resumeTopActivityUncheckedLocked
    该函数定义在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:

    final class ActivityStack {
        ......
        boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
            if (mStackSupervisor.inResumeTopActivity) {
                // Don't even start recursing.
                return false;
            }
    
            boolean result = false;
            try {
                // Protect against recursion.
                mStackSupervisor.inResumeTopActivity = true;
                if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
                    mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
                    mService.updateSleepIfNeededLocked();
                }
                result = resumeTopActivityInnerLocked(prev, options);
            } finally {
                mStackSupervisor.inResumeTopActivity = false;
            }
            return result;
        }
    
        private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
            ......
                // We need to start pausing the current activity so the top one can be resumed...
            final boolean dontWaitForPause = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0;
            boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);
            if (mResumedActivity != null) {
                if (DEBUG_STATES) Slog.d(TAG_STATES,
                        "resumeTopActivityLocked: Pausing " + mResumedActivity);
                pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
            }
        }
    
        final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming,
                boolean dontWait) {
            if (mPausingActivity != null) {
                Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity
                        + " state=" + mPausingActivity.state);
                if (!mService.isSleepingLocked()) {
                    // Avoid recursion among check for sleep and complete pause during sleeping.
                    // Because activity will be paused immediately after resume, just let pause
                    // be completed by the order of activity paused from clients.
                    completePauseLocked(false);
                }
            }
            ActivityRecord prev = mResumedActivity;
            if (prev == null) {
                if (!resuming) {
                    Slog.wtf(TAG, "Trying to pause when nothing is resumed");
                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
                }
                return false;
            }
    
            if (mActivityContainer.mParentActivity == null) {
                // Top level stack, not a child. Look for child stacks.
                mStackSupervisor.pauseChildStacks(prev, userLeaving, uiSleeping, resuming, dontWait);
            }
    
            if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSING: " + prev);
            else if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Start pausing: " + prev);
            mResumedActivity = null;
            mPausingActivity = prev;
            mLastPausedActivity = prev;
            mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
                    || (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ? prev : null;
            ......
    
            if (prev.app != null && prev.app.thread != null) {
                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
                try {
                    EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
                            prev.userId, System.identityHashCode(prev),
                            prev.shortComponentName);
                    mService.updateUsageStats(prev, false);
                    prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
                            userLeaving, prev.configChangeFlags, dontWait);
                } catch (Exception e) {
                    // Ignore exception, if process died other code will cleanup.
                    Slog.w(TAG, "Exception thrown during pause", e);
                    mPausingActivity = null;
                    mLastPausedActivity = null;
                    mLastNoHistoryActivity = null;
                }
            } else {
                mPausingActivity = null;
                mLastPausedActivity = null;
                mLastNoHistoryActivity = null;
            }
            ......
        }
    
    }
    

    这里把Launcher进程中的ApplicationThread对象取出来,通过它来通知Launcher这个Activity它要进入Paused状态了。当然,这里的prev.app.thread是一个ApplicationThread对象的远程接口,通过调用这个远程接口的schedulePauseActivity来通知Launcher进入Paused状态。

    9.ApplicationThreadProxy.schedulePauseActivity
    该函数定义在frameworks/base/core/java/android/app/ApplicationThreadNative.java文件中:

    class ApplicationThreadProxy implements IApplicationThread {
        ......
    
        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();
        }
    
    }
    

    这个函数通过Binder进程通信进入到ApplicationThread.schedulePauseActivity函数中。

    10.ApplicationThread.schedulePauseActivity
    这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中,它是ActivityThread的内部类:

    private class ApplicationThread extends ApplicationThreadNative {
    
        ......
        public final void schedulePauseActivity(IBinder token, boolean finished,
                boolean userLeaving, int configChanges, boolean dontReport) {
            int seq = getLifecycleSeq();
            if (DEBUG_ORDER) Slog.d(TAG, "pauseActivity " + ActivityThread.this
                    + " operation received seq: " + seq);
            sendMessage(
                    finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
                    token,
                    (userLeaving ? USER_LEAVING : 0) | (dontReport ? DONT_REPORT : 0),
                    configChanges,
                    seq);
        }
    
        private void sendMessage(int what, Object obj, int arg1, int arg2, int seq) {
            if (DEBUG_MESSAGES) Slog.v(
                    TAG, "SCHEDULE " + mH.codeToString(what) + " arg1=" + arg1 + " arg2=" + arg2 +
                            "seq= " + seq);
            Message msg = Message.obtain();
            msg.what = what;
            SomeArgs args = SomeArgs.obtain();
            args.arg1 = obj;
            args.argi1 = arg1;
            args.argi2 = arg2;
            args.argi3 = seq;
            msg.obj = args;
            mH.sendMessage(msg);
        }
    
    
        ......  
    
        private final class H extends Handler {  
    
            ......  
    
            public void handleMessage(Message msg) {  
                ......  
                switch (msg.what) {  
    
                ......  
    
                case PAUSE_ACTIVITY: {
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
                    SomeArgs args = (SomeArgs) msg.obj;
                    handlePauseActivity((IBinder) args.arg1, false,
                            (args.argi1 & USER_LEAVING) != 0, args.argi2,
                            (args.argi1 & DONT_REPORT) != 0, args.argi3);
                    maybeSnapshot();
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break; 
    
                ......  
    
                }  
            ......  
    
        } 
    
    
        private void handlePauseActivity(IBinder token, boolean finished,
                boolean userLeaving, int configChanges, boolean dontReport, int seq) {
            ActivityClientRecord r = mActivities.get(token);
            if (DEBUG_ORDER) Slog.d(TAG, "handlePauseActivity " + r + ", seq: " + seq);
            if (!checkAndUpdateLifecycleSeq(seq, r, "pauseActivity")) {
                return;
            }
            if (r != null) {
                //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
                if (userLeaving) {
                    performUserLeavingActivity(r);
                }
    
                r.activity.mConfigChangeFlags |= configChanges;
                performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity");
    
                // Make sure any pending writes are now committed.
                if (r.isPreHoneycomb()) {
                    QueuedWork.waitToFinish();
                }
    
                // Tell the activity manager we have paused.
                if (!dontReport) {
                    try {
                        ActivityManagerNative.getDefault().activityPaused(token);
                    } catch (RemoteException ex) {
                        throw ex.rethrowFromSystemServer();
                    }
                }
                mSomeActivitiesChanged = true;
            }
        }
    
    }
    

    函数首先将Binder引用token转换成ActivityRecord的远程接口ActivityClientRecord,然后做了三个事情:1. 如果userLeaving为true,则通过调用performUserLeavingActivity函数来调用Activity.onUserLeaveHint通知Activity,用户要离开它了;2. 调用performPauseActivity函数来调用Activity.onPause函数,我们知道,在Activity的生命周期中,当它要让位于其它的Activity时,系统就会调用它的onPause函数;3. 它通知ActivityManagerService,这个Activity已经进入Paused状态了,ActivityManagerService现在可以完成未竟的事情,即启动MainActivity了。

    11.ActivityManageProxy.activityPaused

    abstract class ActivityManagerProxy implements IActivityManager
    {
        ......
            public void activityPaused(IBinder token) throws RemoteException
        {
            Parcel data = Parcel.obtain();
            Parcel reply = Parcel.obtain();
            data.writeInterfaceToken(IActivityManager.descriptor);
            data.writeStrongBinder(token);
            mRemote.transact(ACTIVITY_PAUSED_TRANSACTION, data, reply, 0);
            reply.readException();
            data.recycle();
            reply.recycle();
        }
    }
    

    该函数通过Binder驱动程序进入ActivityManagerService.activityPaused函数。

    12.ActivityManagerService.activityPaused
    该函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

    public class ActivityManagerService extends ActivityManagerNativeEx
            implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
        ......
        @Override
        public final void activityPaused(IBinder token) {
            final long origId = Binder.clearCallingIdentity();
            synchronized(this) {
                ActivityStack stack = ActivityRecord.getStackLocked(token);
                if (stack != null) {
                    stack.activityPausedLocked(token, false);
                }
            }
            Binder.restoreCallingIdentity(origId);
        }
    
    }
    

    13.ActivityStack.activityPausedLocked
    该函数定义在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:

    final class ActivityStack {
        final void activityPausedLocked(IBinder token, boolean timeout) {
            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE,
                "Activity paused: token=" + token + ", timeout=" + timeout);
    
            final ActivityRecord r = isInStackLocked(token);
            if (r != null) {
                mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
                if (mPausingActivity == r) {
                    if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSED: " + r
                            + (timeout ? " (due to timeout)" : " (pause complete)"));
                    completePauseLocked(true);
                    return;
                } else {
                    EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE,
                            r.userId, System.identityHashCode(r), r.shortComponentName,
                            mPausingActivity != null
                                ? mPausingActivity.shortComponentName : "(none)");
                    if (r.state == ActivityState.PAUSING) {
                        r.state = ActivityState.PAUSED;
                        if (r.finishing) {
                            if (DEBUG_PAUSE) Slog.v(TAG,
                                    "Executing finish of failed to pause activity: " + r);
                            finishCurrentActivityLocked(r, FINISH_AFTER_VISIBLE, false);
                        }
                    }
                }
            }
            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
        }
    
        //Launcher走完pause状态,调用completePausedLocked
        private void completePauseLocked(boolean resumeNext) {
            ......
            if (resumeNext) {
                final ActivityStack topStack = mStackSupervisor.getFocusedStack();
                if (!mService.isSleepingOrShuttingDownLocked()) {
                    mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);
    
                    // SPRD: bug622737, handle multiple window state correctly.
                    ensureNonResizeableTaskIfNeeded(topStack);
                } else {
                    mStackSupervisor.checkReadyForSleepLocked();
                    ActivityRecord top = topStack.topRunningActivityLocked();
                    if (top == null || (prev != null && top != prev)) {
                        // If there are no more activities available to run, do resume anyway to start
                        // something. Also if the top activity on the stack is not the just paused
                        // activity, we need to go ahead and resume it to ensure we complete an
                        // in-flight app switch.
                        mStackSupervisor.resumeFocusedStackTopActivityLocked();
    
                        // SPRD: bug622737, handle multiple window state correctly.
                        ensureNonResizeableTaskIfNeeded(topStack);
                    }
                }
            }
    
        boolean resumeFocusedStackTopActivityLocked(
                ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
            if (targetStack != null && isFocusedStack(targetStack)) {
                return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
            }
            final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
            if (r == null || r.state != RESUMED) {
                mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
            }
            return false;
        }
    
        boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
            if (mStackSupervisor.inResumeTopActivity) {
                // Don't even start recursing.
                return false;
            }
    
            boolean result = false;
            try {
                // Protect against recursion.
                mStackSupervisor.inResumeTopActivity = true;
                if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
                    mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
                    mService.updateSleepIfNeededLocked();
                }
                result = resumeTopActivityInnerLocked(prev, options);
            } finally {
                mStackSupervisor.inResumeTopActivity = false;
            }
            return result;
        }
    
        private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
            ......
            if (next.app != null && next.app.thread != null) {
                ......
            } else {
                // Whoops, need to restart this activity!
                if (!next.hasBeenLaunched) {
                    next.hasBeenLaunched = true;
                } else {
                    if (SHOW_APP_STARTING_PREVIEW) {
                        next.showStartingWindow(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);
            }
    
            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
            return true;
        }
    
    }
    

    最后调到ActivityStack.resumeTopActivityInnerLocked时,将要启动的应用还没起来,故走else逻辑-调用函数ActivityStackSupervisor.startSpecificActivityLocked.

    14.ActivityStackSupervisor.startSpecificActivityLocked
    该函数定义在frameworks/base/services/java/com/android/server/am/ActivityStackSupervisor.java文件中:

    public final class ActivityStackSupervisor implements DisplayListener {
        ......
        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);
    
            if (r.task != null && r.task.stack != null) {
                r.task.stack.setLaunchTime(r);
            } else {
                Slog.w(TAG, "Stack or task of activity:" + r
                        + " is null, will not setLaunchTime for it.");
            }
    
            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);
        }
    
    }
    

    Launcher点击应用图标启动的进程还未创建,故app为null,如果是应用内部activity中启动另一个activity将会调用realStartActivityLocked。AMS调用startProcessLocked将会为应用创建一个新的进程并在该进程中启动activity。

    15.ActivityManagerService.startProcessLocked
    该函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

    public class ActivityManagerService extends ActivityManagerNativeEx
            implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
        ......
            final ProcessRecord startProcessLocked(String processName,
                ApplicationInfo info, boolean knownToBeDead, int intentFlags,
                String hostingType, ComponentName hostingName, boolean allowWhileBooting,
                boolean isolated, boolean keepIfLarge) {
            return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
                    hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
                    null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
                    null /* crashHandler */);
        }
    
        final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
                boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
                boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
                String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
            long startTime = SystemClock.elapsedRealtime();
            ProcessRecord app;
            if (!isolated) {
                app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
                checkTime(startTime, "startProcess: after getProcessRecord");
    
                if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
                    // If we are in the background, then check to see if this process
                    // is bad.  If so, we will just silently fail.
                    if (mAppErrors.isBadProcessLocked(info)) {
                        if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
                                + "/" + info.processName);
                        return null;
                    }
                } else {
                    // When the user is explicitly starting a process, then clear its
                    // crash count so that we won't make it bad until they see at
                    // least one crash dialog again, and make the process good again
                    // if it had been bad.
                    if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
                            + "/" + info.processName);
                    mAppErrors.resetProcessCrashTimeLocked(info);
                    if (mAppErrors.isBadProcessLocked(info)) {
                        EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
                                UserHandle.getUserId(info.uid), info.uid,
                                info.processName);
                        mAppErrors.clearBadProcessLocked(info);
                        if (app != null) {
                            app.bad = false;
                        }
                    }
                }
            } else {
                // If this is an isolated process, it can't re-use an existing process.
                app = null;
            }
    
            ......
    
            checkTime(startTime, "startProcess: stepping in to startProcess");
            startProcessLocked(
                    app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
            checkTime(startTime, "startProcess: done starting proc!");
            return (app.pid != 0) ? app : null;
        }
    
        private final void startProcessLocked(ProcessRecord app, String hostingType,
                String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
            long startTime = SystemClock.elapsedRealtime();
            if (app.pid > 0 && app.pid != MY_PID) {
                checkTime(startTime, "startProcess: removing from pids map");
                synchronized (mPidsSelfLocked) {
                    mPidsSelfLocked.remove(app.pid);
                    mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
                }
                checkTime(startTime, "startProcess: done removing from pids map");
                app.setPid(0);
            }
            ......
            try {
                ......
                // Start the process.  It will either succeed and return a result containing
                // the PID of the new process, or else throw a RuntimeException.
                boolean isActivityProcess = (entryPoint == null);
                if (entryPoint == null) entryPoint = "android.app.ActivityThread";
                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
                        app.processName);
                checkTime(startTime, "startProcess: asking zygote to start proc");
                Process.ProcessStartResult startResult = Process.start(entryPoint,
                        app.processName, uid, uid, gids, debugFlags, mountExternal,
                        app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
                        app.info.dataDir, entryPointArgs);
               ......
           }
       }
       ......
    }
    

    这里主要是调用Process.start接口来创建一个新的进程,新的进程会导入android.app.ActivityThread类,并且执行它的main函数,每一个应用程序都有一个ActivityThread实例来对应。

    16.ActivityThread.main
    该函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:

    public final class ActivityThread {  
    
        ......  
    
        private final void attach(boolean system) {  
            ......  
    
            mSystemThread = system;  
            if (!system) {  
    
                ......  
    
                IActivityManager mgr = ActivityManagerNative.getDefault();  
                try {  
                    mgr.attachApplication(mAppThread);  
                } catch (RemoteException ex) {
                    ......  
                }  
            } else {  
    
                ......  
    
            }  
        }  
    
        ......  
    
        public static void main(String[] args) {
            ......
    
            Looper.prepareMainLooper();
    
            ActivityThread thread = new ActivityThread();
            thread.attach(false);
            ......
            Looper.loop();
    
            throw new RuntimeException("Main thread loop unexpectedly exited");
        }
    
    
    } 
    

    这个函数在进程中创建一个ActivityThread实例,然后调用它的attach函数,接着就进入消息循环了,直到最后进程退出。
    函数attach最终调用了ActivityManagerService的远程接口ActivityManagerProxy的attachApplication函数,传入的参数是mAppThread,这是一个ApplicationThread类型的Binder对象,它的作用是用来进行进程间通信的。

    17.ActivityManagerProxy.attachApplication
    该函数定义在frameworks/base/core/java/android/app/ActivityManagerNative.java文件中:

    class ActivityManagerProxy implements IActivityManager  
    {  
        ......  
    
        public void attachApplication(IApplicationThread app) throws RemoteException
        {
            Parcel data = Parcel.obtain();
            Parcel reply = Parcel.obtain();
            data.writeInterfaceToken(IActivityManager.descriptor);
            data.writeStrongBinder(app.asBinder());
            mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);
            reply.readException();
            data.recycle();
            reply.recycle();
        }  
    
        ......  
    
    }
    

    这里通过Binder驱动程序,最后进入ActivityManagerService的attachApplication函数中。

    18.ActivityManagerService.attachApplication
    该函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

    public final class ActivityManagerService extends ActivityManagerNative  
            implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {  
    
        ......  
    
        @Override
        public void attachApplication(IApplicationThread thread) {
            synchronized (this) {
                int callingPid = Binder.getCallingPid();
                final long origId = Binder.clearCallingIdentity();
                attachApplicationLocked(thread, callingPid);
                Binder.restoreCallingIdentity(origId);
            }
        }
    
        private final boolean attachApplicationLocked(IApplicationThread thread,
                int pid) { 
            ......
            boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
            ......
            if (normalMode) {
                try {
                    if (mStackSupervisor.attachApplicationLocked(app)) {
                        didSomething = true;
                    }
                } catch (Exception e) {
                    ......
                }
            }
        } 
    
        ......  
    
    }
    

    attachApplicationLocked接着调用ActivityStackSupervisor.attachApplicationLocked接口。

    19.ActivityStackSupervisor.attachApplicationLocked
    该函数定义在frameworks/base/services/java/com/android/server/am/ActivityStackSupervisor.java文件中:

    public final class ActivityStackSupervisor implements DisplayListener {
        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) {
                    ......
                    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) {
                                ......
                            }
                        }
                    }
                }
            }
            if (!didSomething) {
                ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
            }
            return didSomething;
        }
    
        final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
                boolean andResume, boolean checkConfig) throws RemoteException {
            ......
            try {
                ......
    
                if (andResume) {
                    app.hasShownUi = true;
                    app.pendingUiClean = true;
                }
                app.forceProcessStateUpTo(mService.mTopProcessState);
                app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                        System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
                        new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage,
                        task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
                        newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
    
                ......
            } catch (RemoteException e) {
                ......
            }
        }
    
    }
    

    这里最终通过app.thread进入到ApplicationThreadProxy的scheduleLaunchActivity函数中,注意,这里的第二个参数r,是一个ActivityRecord类型的Binder对象,用来作来这个Activity的token值。

    20.ApplicationThreadProxy.scheduleLaunchActivity
    该函数定义在frameworks/base/core/java/android/app/ApplicationThreadNative.java文件中:

    class ApplicationThreadProxy implements IApplicationThread {  
    
        ......  
    
        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) throws RemoteException {
            Parcel data = Parcel.obtain();
            data.writeInterfaceToken(IApplicationThread.descriptor);
            intent.writeToParcel(data, 0);
            data.writeStrongBinder(token);
            data.writeInt(ident);
            info.writeToParcel(data, 0);
            curConfig.writeToParcel(data, 0);
            if (overrideConfig != null) {
                data.writeInt(1);
                overrideConfig.writeToParcel(data, 0);
            } else {
                data.writeInt(0);
            }
            compatInfo.writeToParcel(data, 0);
            data.writeString(referrer);
            data.writeStrongBinder(voiceInteractor != null ? voiceInteractor.asBinder() : null);
            data.writeInt(procState);
            data.writeBundle(state);
            data.writePersistableBundle(persistentState);
            data.writeTypedList(pendingResults);
            data.writeTypedList(pendingNewIntents);
            data.writeInt(notResumed ? 1 : 0);
            data.writeInt(isForward ? 1 : 0);
            if (profilerInfo != null) {
                data.writeInt(1);
                profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
            } else {
                data.writeInt(0);
            }
            mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION, data, null,
                    IBinder.FLAG_ONEWAY);
            data.recycle();
        } 
    
        ......  
    
    } 
    

    还是通过Binder驱动程序进入ApplicationThread的scheduleLaunchActivity函数中。

    21.ApplicationThread.scheduleLaunchActivity
    函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:

    public final class ActivityThread {
        ......
        private final class ApplicationThread extends ApplicationThreadNative { 
            @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);
            }
        }
    
        private void sendMessage(int what, Object obj, int arg1) {
            sendMessage(what, obj, arg1, 0, false);
        }
    
        private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
            if (DEBUG_MESSAGES) Slog.v(
                TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
                + ": " + arg1 + " / " + obj);
            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 final class H extends Handler {  
    
            ......  
    
            public void handleMessage(Message msg) {  
                ......  
                switch (msg.what) {  
                    case LAUNCH_ACTIVITY: {
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
                        final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
    
                        r.packageInfo = getPackageInfoNoCheck(
                                r.activityInfo.applicationInfo, r.compatInfo);
                        handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    } break; 
                ......  
                }  
    
            ......  
    
        } 
    
        private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
            ......
            Activity a = performLaunchActivity(r, customIntent);
    
            if (a != null) {
                r.createdConfig = new Configuration(mConfiguration);
                reportSizeConfigurations(r);
                Bundle oldState = r.state;
                handleResumeActivity(r.token, false, r.isForward,
                        !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
               ......
            } else {
                ......
            }
        }
    
        private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
            // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
    
            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);
            }
    
            Activity activity = null;
            try {
                java.lang.ClassLoader cl = r.packageInfo.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) {
                    Context appContext = createBaseContextForActivity(r, activity);
                    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.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);
    
                    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);
                    }
                    if (!activity.mCalled) {
                        throw new SuperNotCalledException(
                            "Activity " + r.intent.getComponent().toShortString() +
                            " did not call through to super.onCreate()");
                    }
                    r.activity = activity;
                    r.stopped = true;
                    if (!r.activity.mFinished) {
                        activity.performStart();
                        r.stopped = false;
                    }
                    if (!r.activity.mFinished) {
                        if (r.isPersistable()) {
                            if (r.state != null || r.persistentState != null) {
                                mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
                                        r.persistentState);
                            }
                        } else if (r.state != null) {
                            mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
                        }
                    }
                    if (!r.activity.mFinished) {
                        activity.mCalled = false;
                        if (r.isPersistable()) {
                            mInstrumentation.callActivityOnPostCreate(activity, r.state,
                                    r.persistentState);
                        } else {
                            mInstrumentation.callActivityOnPostCreate(activity, r.state);
                        }
                        if (!activity.mCalled) {
                            throw new SuperNotCalledException(
                                "Activity " + r.intent.getComponent().toShortString() +
                                " did not call through to super.onPostCreate()");
                        }
                    }
                }
                r.paused = true;
    
                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;
        }
    }
    

    先调用performLaunchActivity函数来加载Activity,然后调用它的onCreate函数,最后回到handleLaunchActivity函数时,再调用handleResumeActivity函数来使这个Activity进入Resumed状态,即会调用这个Activity的onResume函数,这是遵循Activity的生命周期的。其中performLaunchActivity中是通过函数Instrumentation.callActivityOnCreate来间接调用Activity的onCreate函数的,

    Application app = r.packageInfo.makeApplication(false, mInstrumentation);
    

    这句是创建Application;

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

    这里将Application和activity关联起来,因此一个应用都有一个Application。

    相关文章

      网友评论

          本文标题:Launcher点击图标启动App流程分析(基于Android

          本文链接:https://www.haomeiwen.com/subject/szelhltx.html