Activity启动流程源码分析之Launcher启动(二)

1、前述

在前一篇文章中我们简要的介绍Activity的启动流程Activity启动流程源码分析之入门(一),当时只是简单的分析了一下流程,而且在上一篇博客中我们也说了Activity的两种启动方式,现在我们就来分析其中的第一种方式——Launcher启动,这种启动方式的特点是会创建一个新的进程来加载相应的Activity(基于Android5.1源码)。

2、Activity启动流程时序图

好啦,接下来我们先看一下Launcher启动Activity的时序图:

好啦,接下来我们将上述时序图用代码来分析一下。

3、Activity启动流程步骤说明

(1)Launcher.startActivitySafely()

Android中桌面的应用程序都是由Launcher启动的,其中Launcher本身也是一个应用,当应用程序安装完成后都会在桌面创建相应的应用程序图标,点击这个图标,Launcher就会将其启动起来。

源码:packages/apps/Launcher2

public final class Launcher extends Activity
        implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks,View.OnTouchListener {

    /**
     * Launches the intent referred by the clicked shortcut.
     *
     * @param v The view representing the clicked shortcut.
     */
    public void onClick(View v) {
        //......
        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()));
            //这里调用startActivitySafely方法
            boolean success = startActivitySafely(v, intent, tag);

            if (success && v instanceof BubbleTextView) {
                mWaitingForResume = (BubbleTextView) v;
                mWaitingForResume.setStayPressed(true);
            }
        } else if (tag instanceof FolderInfo) {
            if (v instanceof FolderIcon) {
                FolderIcon fi = (FolderIcon) v;
                handleFolderClick(fi);
            }
        } else if (v == mAllAppsButton) {
            if (isAllAppsVisible()) {
                showWorkspace(true);
            } else {
                onClickAllAppsButton(v);
            }
        }
    }

    boolean startActivitySafely(View v, Intent intent, Object tag) {
        boolean success = false;
        try {
            //这里调用startActivity方法
            success = startActivity(v, intent, tag);
        } catch (ActivityNotFoundException e) {
            Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
            Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);
        }
        return success;
    }
}

(2)Activity.startActivity()

由于Launcher是继承于Activity,所以在startActivitySafely中调用的startActivity方法其实就是Activity中的方法。

源码:frameworks/base/core/java/android/app/Activity.java

public class Activity extends ContextThemeWrapper
        implements LayoutInflater.Factory,
        Window.Callback, KeyEvent.Callback,
        OnCreateContextMenuListener, ComponentCallbacks {
    //......
    @Override
    public void startActivity(Intent intent) {
        startActivityForResult(intent, -1);
    }
    //......
}  

这个函数很简单,通过调用startActivityForResult方法来进一步操作。

(3)Activity.startActivityForResult()

源码:frameworks/base/core/java/android/app/Activity.java

public class Activity extends ContextThemeWrapper
        implements LayoutInflater.Factory,
        Window.Callback, KeyEvent.Callback,
        OnCreateContextMenuListener, ComponentCallbacks {
    //......
    public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
        if (mParent == null) {
            //这里调用Instrumentation对象的execStartActivity方法
            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());
            }
            //......
    }
    //......
}  

这里的mInstrumentation和mMainThread都是Activity的成员变量,mMainThread的类型是ActivityThread,表示应用程序的主线程。其通过mMainThread.getApplicationThread()获得ApplicationThread成员变量,ApplicationThread是一个Binder对象,ActivityManagerService就是通过它和ActivityThread进行通信,这里的mMainThread代表的是Launcher应用程序的进程。

(4)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;
        //......
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess();
            //这里调用ActivityManagerProxy对象的startActivity方法
            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) {
        }
        return null;
    }
}

这里通过ActivityManagerNative.getDefault()方法获得ActivityManagerService的远程代理ActivityManagerProxy对象。

(5)ActivityManagerProxy.startActivity()

源码:frameworks/base/core/java/android/app/ActivityManagerNative.java

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

在代码的注释位置通过Binder调用ActivityManagerNative类中的onTransact方法,其识别码为START_ACTIVITY_TRANSACTION,并调用ActivityManagerNative类的startActivity方法,由于ActivityManagerService继承于ActivityManagerNative类,所以最终调用了ActivityManagerService中的startActivity方法。

(6)ActivityManagerService.startActivity()

源码:frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

 @Override
    public final int startActivity(IApplicationThread caller, String callingPackage,Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,int startFlags, ProfilerInfo profilerInfo, Bundle options) {
        //这里调用startActivityAsUser方法
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
            resultWho, requestCode, startFlags, profilerInfo, options,
            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 options, int userId) {
        enforceNotIsolatedCaller("startActivity");
        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
                false, ALLOW_FULL_ONLY, "startActivity", null);
        // TODO: Switch to user app stacks here.
        //这里调用startActivityMayWait方法
        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,profilerInfo, null, null, options, userId, null, null);
    }

进入到ActivityManagerService.startActivity方法后,调用本类的startActivityAsUser方法,这里只是简单的将操作转发给ActivityStackSupervisor.startActivityMayWait方法。

(7)ActivityStackSupervisor.startActivityMayWait()

源码:frameworks/base/services/java/com/android/server/am/ActivityStackSupervisor.java

public final class ActivityStackSupervisor implements DisplayListener {

     final int startActivityMayWait(IApplicationThread caller, int callingUid,String callingPackage, Intent intent, ...) {
    //......
    int res = startActivityLocked(caller, intent, resolvedType, aInfo,
                    voiceSession, ...);
    }
    //......
}

紧接着调用本类的startActivityLocked方法。

(8)ActivityStackSupervisor.startActivityLocked()

源码:frameworks/base/services/java/com/android/server/am/ActivityStackSupervisor.java

final int startActivityLocked(IApplicationThread caller,
            Intent intent, String resolvedType, ActivityInfo aInfo,...) {

    err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,startFlags, true, options, inTask);
}

紧接着调用本类的startActivityUncheckedLocked方法。

(9)ActivityStackSupervisor.startActivityUncheckedLocked()方法

源码:frameworks/base/services/java/com/android/server/am/ActivityStackSupervisor.java

final int startActivityUncheckedLocked(ActivityRecord r, ActivityRecord sourceRecord,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,boolean doResume, Bundle options, TaskRecord inTask) {
    //......
    ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
        targetStack.mLastPausedActivity = null;
        //此处调用ActivityStack.startActivityLocked方法
        targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
        if (!launchTaskBehind) {
            // Don‘t set focus on an activity that‘s going to the back.
            mService.setFocusedActivityLocked(r, "startedActivity");
        }
        return ActivityManager.START_SUCCESS;
}

这段代码相当的长,并在最终调用ActivityStack.startActivityLocked方法。

(10)ActivityStack.startActivityLocked()

源码:frameworks/base/services/java/com/android/server/am/ActivityStack.java

final void startActivityLocked(ActivityRecord r, boolean newTask,
            boolean doResume, boolean keepCurTransition, Bundle options) {
        TaskRecord rTask = r.task;
        final int taskId = rTask.taskId;

        if (doResume) {
            mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
        }
}

由于这里的参数doResume在之前的方法中传入的是true,于是有调用了mStackSupervisor对象的resumeTopActivitiesLocked方法。

(11)ActivityStackSupervisor.resumeTopActivitiesLocked()

源码:frameworks/base/services/java/com/android/server/am/ActivityStackSupervisor.java

boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,Bundle targetOptions) {
        if (targetStack == null) {
            targetStack = getFocusedStack();
        }
        // Do targetStack first.
        boolean result = false;
        if (isFrontStack(targetStack)) {
            //此处又调用了ActivityStack.resumeTopActivityLocked方法
            result = targetStack.resumeTopActivityLocked(target, targetOptions);
        }
}

进入到resumeTopActivityLocked方法。

(12)ActivityStack.resumeTopActivityLocked()

源码:frameworks/base/services/java/com/android/server/am/ActivityStack.java

final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle 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();
            }
            //这里调用resumeTopActivityInnerLocked方法
            result = resumeTopActivityInnerLocked(prev, options);
        } finally {
            mStackSupervisor.inResumeTopActivity = false;
        }
        return result;
    }

(13)ActivityStack.resumeTopActivityInnerLocked()

源码:frameworks/base/services/java/com/android/server/am/ActivityStack.java

final boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
    if ((parent != null && parent.state != ActivityState.RESUMED) ||
                !mActivityContainer.isAttachedLocked()) {
            return false;
        }

    // Find the first activity that is not finishing.
        final ActivityRecord next = topRunningActivityLocked(null);

    // If the top activity is the resumed one, nothing to do.
        if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
                    mStackSupervisor.allResumedActivitiesComplete()) {
        //......
        }

    // If we are sleeping, and there is no resumed activity, and the top
        // activity is paused, well that is the state we want.
        if (mService.isSleepingOrShuttingDown()
                && mLastPausedActivity == next
                && mStackSupervisor.allPausedActivitiesComplete()) {
                //......
        }

    if (mResumedActivity != null) {
    //这里调用startPausingLocked方法
            pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
        }
}

这段代码做的事情还是比较多的,函数首先通过调用topRunningActivityLocked方法获得堆栈顶端的Activity,保存到next中。

然后看要启动的Activity是否就是当前处理Resumed状态的Activity,如果是就不做任何处理,如果不满足就需要将Resumed状态的Activity推入Paused状态,然后才能启动新的Activity。但再这之前首先要检查一下是否有Activity正处于Paused状态,如果有的话这个Resumed状态的Activity就要稍后才能进入Paused状态了,这样才能保证所有需要进入Paused状态的Activity串行处理,这里就需要调用startPausingLocked方法把Launcher推入Paused状态。

我们进入startPausingLocked方法。

(14)ActivityStack.startPausingLocked()

源码:frameworks/base/services/java/com/android/server/am/ActivityStack.java

final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming,boolean dontWait) {
    //调用IApplicationThread对象的schedulePauseActivity方法
    prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,userLeaving, prev.configChangeFlags, dontWait);

}

这里的prev.app.thread是一个远程IApplicationThread对象,通过调用这个远程对象的schedulePauseActivity来通知Launcher进入Paused状态,而ApplicationThreadProxy是IApplicationThread对象的代理类,另外就是此刻由于Launcher还没Pause,所以prev.finishing属性为false。

(15)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);
        //这里通过SCHEDULE_PAUSE_ACTIVITY_TRANSACTION识别码调用onTransact方法
        mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null,
                IBinder.FLAG_ONEWAY);
        data.recycle();
    }
}

在代码的注释位置通过Binder调用ApplicationThreadNative类中的onTransact方法,其识别码为SCHEDULE_PAUSE_ACTIVITY_TRANSACTION,并调用ApplicationThreadNative类的schedulePauseActivity方法,由于ApplicationThread继承于ApplicationThreadNative类,所以最终调用了ApplicationThread中的schedulePauseActivity方法。

(16)ApplicationThread.schedulePauseActivity()

源码:frameworks/base/core/java/android/app/ActivityThread.java

这是ActivityThread的内部类

public final class ActivityThread {

    private class ApplicationThread extends ApplicationThreadNative {

        public final void schedulePauseActivity(IBinder token, boolean finished,boolean userLeaving, int configChanges, boolean dontReport) {
            //通过发送Message来处理消息
            sendMessage(
                    finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
                    token,
                    (userLeaving ? 1 : 0) | (dontReport ? 2 : 0),
                    configChanges);
        }
    }
}

在(14)步时已经说了,这里的finished变量是false,所以我们进入到识别码为PAUSE_ACTIVITY的Handler中。

(17)ActivityThread .H

源码:frameworks/base/core/java/android/app/ActivityThread.java

public final class ActivityThread {

    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");
                    //此处调用handlePauseActivity
                    handlePauseActivity((IBinder)msg.obj, false, (msg.arg1&1) != 0, msg.arg2,(msg.arg1&2) != 0);
                    maybeSnapshot();
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
            }
        }
    }
}

可以看出此处调用了ActivityThread.handlePauseActivity方法进行处理,另外说一句此处的msg.obj是一个ActivityRecord对象的引用,它代表的是Launcher这个Activity。

(18)ActivityThread.handlePauseActivity()

源码:frameworks/base/core/java/android/app/ActivityThread.java

private void handlePauseActivity(IBinder token, boolean finished,
            boolean userLeaving, int configChanges, boolean dontReport) {
        ActivityClientRecord r = mActivities.get(token);
        if (r != null) {
            //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
            //当userLeaving为true,将执行performUserLeavingActivity()方法
            if (userLeaving) {
                performUserLeavingActivity(r);
            }

            r.activity.mConfigChangeFlags |= configChanges;
            //执行performPauseActivity
            performPauseActivity(token, finished, r.isPreHoneycomb());

            // Make sure any pending writes are now committed.
            if (r.isPreHoneycomb()) {
                QueuedWork.waitToFinish();
            }

            // Tell the activity manager we have paused.
            if (!dontReport) {
                try {
                //执行ActivityManagerService.activityPaused方法
                   ActivityManagerNative.getDefault().activityPaused(token);
                } catch (RemoteException ex) {
                }
            }
            mSomeActivitiesChanged = true;
        }
    }

这个方法做了三件事:

(1)当userLeaving为true时,通过调用performUserLeavingActivity方法来调用Activity.performUserLeaving方法通知当前Activity即将要退出了。

(2)调用performPauseActivity方法来调用Activity.onPause方法。

(3)调用ActivityManagerNative.getDefault()对象的activityPaused方法来通知ActivityManagerService处理剩下的事情。

(19)ActivityManagerProxy.activityPaused()

源码:frameworks/base/core/java/android/app/ActivityManagerNative.java

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

在(18)步骤中通过ActivityManagerNative.getDefault()获得ActivityManagerNative的代理对象ActivityManagerProxy,并调用他的activityPaused方法。

通过Binder机制调用ActivityManagerNative的onTransact方法,其识别码为ACTIVITY_PAUSED_TRANSACTION,并最终调用ActivityManagerService的activityPaused方法。

(20)ActivityManagerService.activityPaused()

源码:frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

public class ActivityManagerService extends ActivityManagerNative
        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);
    }
}

再次进入到ActivityStack的activityPausedLocked方法中。

(21)ActivityStack.activityPausedLocked()

源码:frameworks/base/services/java/com/android/server/am/ActivityStack.java

final class ActivityStack {

    final void activityPausedLocked(IBinder token, boolean timeout) {
        //......
        final ActivityRecord r = isInStackLocked(token);
        if (r != null) {
            mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
            if (mPausingActivity == r) {
                if (DEBUG_STATES) Slog.v(TAG, "Moving to PAUSED: " + r
                        + (timeout ? " (due to timeout)" : " (pause complete)"));
                completePauseLocked(true);
            }
            //......
        }
    }
}

在上面的(17)步骤中我们说了此处的参数token即是ActivityRecord,同时也是Launcher这个Activity。此处的r就是我们当前需要Pause的对象,所以条件成立进入completePauseLocked方法。

(22)ActivityStack.completePauseLocked()

源码:frameworks/base/services/java/com/android/server/am/ActivityStack.java

 private void completePauseLocked(boolean resumeNext) {
        ActivityRecord prev = mPausingActivity;
        //......
        if (resumeNext) {
            final ActivityStack topStack = mStackSupervisor.getFocusedStack();
            if (!mService.isSleepingOrShuttingDown()) {
                mStackSupervisor.resumeTopActivitiesLocked(topStack, prev, null);
            } else {
                mStackSupervisor.checkReadyForSleepLocked();
                ActivityRecord top = topStack.topRunningActivityLocked(null);
                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.resumeTopActivitiesLocked(topStack, null, null);
                }
            }
        }
}

此处再次调用了mStackSupervisor对象的resumeTopActivitiesLocked方法。

(23)ActivityStackSupervisor.resumeTopActivitiesLocked()

源码:frameworks/base/services/java/com/android/server/am/ActivityStackSupervisor.java

boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
            Bundle targetOptions) {
        if (targetStack == null) {
            targetStack = getFocusedStack();
        }
        // Do targetStack first.
        boolean result = false;
        if (isFrontStack(targetStack)) {
            result = targetStack.resumeTopActivityLocked(target, targetOptions);
        }
}

(24)ActivityStack.resumeTopActivityLocked()

源码:frameworks/base/services/java/com/android/server/am/ActivityStack.java

final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle 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;
    }

(25)ActivityStack.resumeTopActivityInnerLocked()

源码:frameworks/base/services/java/com/android/server/am/ActivityStack.java

final boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
        if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen("");
        //......

         mStackSupervisor.startSpecificActivityLocked(next, true, false);
                if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
                return true;
}

我们进入到startSpecificActivityLocked方法中。

(26)ActivityStackSupervisor.startSpecificActivityLocked()

源码:frameworks/base/services/java/com/android/server/am/ActivityStackSupervisor.java

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 (app != null && app.thread != null) {
            realStartActivityLocked(r, app, andResume, checkConfig);
                return;
        }
        //......

    //我们主要来分析这里
    mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
}

我们接下来分析一下这段代码:

ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);

这里由于是第一次启动应用程序的Activity,所以取回来的app为null。在Activity应用程序中的AndroidManifest.xml配置文件中,我们没有指定Application标签的process属性,系统就会默认使用应用程序包名作为进程名。每一个应用程序都有自己的uid,因此,这里uid + processName的组合就可以为每一个应用程序创建一个ProcessRecord。当然,我们也可以在不同的应用程序中的AndroidManifest.xml文件的application标签或者activity标签中显式指定相同的process属性值,那样不同的应用程序也可以在同一个进程中启动。

最后执行ActivityManagerService.startProcessLocked方法。

(27)ActivityManagerService.startProcessLocked()

源码:frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

public class ActivityManagerService extends ActivityManagerNative
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {

        final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,...) {
        boolean isActivityProcess = (entryPoint == null);
            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
            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对象对应着,同时每个应用程序都是从ActivityThread的main函数开始的。

(28)ActivityThread.main()

源码:frameworks/base/core/java/android/app/ActivityThread.java

public static void main(String[] args) {
        //......

        Process.setArgV0("<pre-initialized>");

        Looper.prepareMainLooper();

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

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

        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }

        Looper.loop();

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

    private void attach(boolean system) {
        final IActivityManager mgr = ActivityManagerNative.getDefault();
            try {
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                // Ignore
            }
    }

main函数创建ActivityThread对象,然后调用它的attach方法,紧接着最后进入消息循环,直至进程退出。

而attach方法通过ActivityManagerNative.getDefault()获得ActivityManagerProxy代理对象,然后调用其attachApplication方法,这个方法最终在ActivityManagerService中实现,传入的参数是ApplicationThread类型的Binder对象,用于进程间通信。

(29)ActivityManagerService.attachApplication()

源码:frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

@Override
    public final void attachApplication(IApplicationThread thread) {
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final long origId = Binder.clearCallingIdentity();
            attachApplicationLocked(thread, callingPid);
            Binder.restoreCallingIdentity(origId);
    }

紧接着直接调用attachApplicationLocked方法。

(30)ActivityManagerService.attachApplicationLocked()

源码:frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) {

             // See if the top visible activity is waiting to run in this process...
        if (normalMode) {
            try {
            //这里调用mStackSupervisor对象的attachApplicationLocked方法
                if (mStackSupervisor.attachApplicationLocked(app)) {
                    didSomething = true;
                }
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
        }
}

(31)ActivityStackSupervisor.attachApplicationLocked()

源码:frameworks/base/services/java/com/android/server/am/ActivityStackSupervisor.java

 boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
                //......
                ActivityRecord hr = stack.topRunningActivityLocked(null);
                if (hr != null) {
                    if (hr.app == null && app.uid == hr.info.applicationInfo.uid&& processName.equals(hr.processName)) {
                        try {
                            //这里调用真正启动Activity的方法
                            if (realStartActivityLocked(hr, app, true, true)) {
                                didSomething = true;
                            }
                        } catch (RemoteException e) {
                            //......
                        }
                    }
                }
            }
        }
        //......
        return didSomething;
    }

这里通过topRunningActivityLocked方法从栈顶端取出要启动的Activity,然后通过realStartActivityLocked方法来启动它。

(32)ActivityStackSupervisor.realStartActivityLocked()

源码:frameworks/base/services/java/com/android/server/am/ActivityStackSupervisor.java

final boolean realStartActivityLocked(ActivityRecord r,
            ProcessRecord app, boolean andResume, boolean checkConfig)
            throws RemoteException {
            //这里调用IApplicationThread对象的scheduleLaunchActivity
            app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
                    r.compat, r.launchedFromPackage, r.task.voiceInteractor, app.repProcState,
                    r.icicle, r.persistentState, results, newIntents, !andResume,
                    mService.isNextTransitionForward(), profilerInfo);

    }

这里可以看出app.thread对象就是IApplicationThread对象,而该对象的代理对象是ApplicationThreadProxy,所以这里调用ApplicationThreadProxy.scheduleLaunchActivity方法。

(33)ApplicationThreadProxy.scheduleLaunchActivity()

源码:frameworks/base/core/java/android/app/ApplicationThreadNative.java

public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
            ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,...) throws RemoteException {
        Parcel data = Parcel.obtain();
        data.writeInterfaceToken(IApplicationThread.descriptor);
        intent.writeToParcel(data, 0);
        data.writeStrongBinder(token);
        //......
        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对象调用ApplicationThreadNative的onTransact方法,其识别码是SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION,而ApplicationThreadNative的实现类是ApplicationThread类,所以这里间接的调用了ApplicationThread的scheduleLaunchActivity方法。

(34)ApplicationThread.scheduleLaunchActivity()

源码:frameworks/base/core/java/android/app/ActivityThread.java

 public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,ActivityInfo info,...) {

            updateProcessState(procState, false);
            ActivityClientRecord r = new ActivityClientRecord();
            //......
            r.profilerInfo = profilerInfo;
            updatePendingConfiguration(curConfig);

            sendMessage(H.LAUNCH_ACTIVITY, r);
        }

这里通过H这个Handler来发送和处理消息。

(35)ActivityThread.H

源码:frameworks/base/core/java/android/app/ActivityThread.java

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);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;
            }
}

这里调用本类的handleLaunchActivity方法。

(36)ActivityThread.handleLaunchActivity()

源码:frameworks/base/core/java/android/app/ActivityThread.java

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    Activity a = performLaunchActivity(r, customIntent);

        if (a != null) {
            r.createdConfig = new Configuration(mConfiguration);
            Bundle oldState = r.state;
            handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed);
        //......
        }
    //......
}

这里先调用performLaunchActivity方法来加载Activity,这个方法内部会调用OnCreate方法,并返回当前Activity,当Activity!=null时将执行handleResumeActivity方法,使这个Activity在调用OnResume方法,这里按照Activity的生命周期执行。

我们直接进入performLaunchActivity方法。

(37)ActivityThread.performLaunchActivity()

源码:frameworks/base/core/java/android/app/ActivityThread.java

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");

        //(1)这里主要用于收集Activity的相关信息(package和component)
        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 {
            //(2)这里通过类加载器ClassLoader加载当前需要启动的Activity
            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 {
             //(3)创建Application对象,主要是根据Manifest文件配置进行创建
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);
            //......
            if (activity != null) {
                //(4)创建上下文信息,并通过attach方法将上下文信息设置到Activity中
                Context appContext = createBaseContextForActivity(r, activity);
                //......
                activity.attach(appContext, this, getInstrumentation(), r.token, r.ident, app, r.intent, r.activityInfo, title, r.parent,r.embeddedID, r.lastNonConfigurationInstances, config,r.referrer, r.voiceInteractor);

                //......

                activity.mCalled = false;
                if (r.isPersistable()) {
                    //(5)通过调用mInstrumentation对象的callActivityOnCreate方法并最终调用Activity的OnCreate方法
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }

        }
    }

上面的源码的我们对重要的点都做了分析,此处就不一一分析了,我们紧接着进入mInstrumentation对象的callActivityOnCreate方法。

(38)Instrumentation.callActivityOnCreate()

源码:frameworks/base/core/java/android/app/Instrumentation.java

/**
     * Perform calling of an activity‘s {@link Activity#onCreate}
     * method.  The default implementation simply calls through to that method.
     *
     * @param activity The activity being created.
     * @param icicle The previously frozen state (or null) to pass through to onCreate().
     */
    public void callActivityOnCreate(Activity activity, Bundle icicle) {
        prePerformCreate(activity);
        activity.performCreate(icicle);
        postPerformCreate(activity);
    }

在调用Activity的performCreate方法前后,会分别调用一个prePerformCreate和postPerformCreate方法做处理。

(39)Activity.performCreate()

源码:frameworks/base/core/java/android/app/Activity.java

final void performCreate(Bundle icicle) {
        bringUpThreadPriority();
        onCreate(icicle);
        mActivityTransitionState.readState(icicle);
        performCreateCommon();
    }

终于看到Activity的OnCreate方法调用了吧,哈哈到此整个Activity的启动流程我们就看完啦,也就是说现在MainActivity也就启动起来了。

4、总结

从上面的启动流程来看,平时我们启动一个Activity时,在应用的框架层还是做了很多的事情,由于上面的步骤较多,我们准备将它们分分类。

  1. (1)-(13)Launcher通过Binder通信通知ActivityManagerService要启动一个Activity。
  2. (14)-(22)ActivityManagerService通过Binder通信使Launcher进入Paused状态,并且准备创建新的进程。
  3. (23)-(27)ActivityManagerService通过startProcessLocked方法创建新的进程ActivityThread,准备启动新的Activity。
  4. (28)-(39)新的进程启动后ActivityThread开始通过Binder通信使ActivityManagerService启动新的Activity。

好啦,这边博客到此就全部结束啦,整个篇幅还是蛮长的,下篇我们将阐述Activity内部启动新的Activity的启动流程,即新的Activity和启动它的Activity在同一进程中Activity启动流程源码分析之startActivity启动(三)

时间: 2024-10-08 02:48:27

Activity启动流程源码分析之Launcher启动(二)的相关文章

Android系统默认Home应用程序(Launcher)的启动过程源码分析

在前面一篇文章中,我们分析了Android系统在启动时安装应用程序的过程,这些应用程序安装好之后,还须要有一个Home应用程序来负责把它们在桌面上展示出来,在Android系统中,这个默认的Home应用程序就是Launcher了,本文将详细分析Launcher应用程序的启动过程. Android系统的Home应用程序Launcher是由ActivityManagerService启动的,而ActivityManagerService和PackageManagerService一样,都是在开机时由

JobTracker启动流程源码级分析

org.apache.hadoop.mapred.JobTracker类是个独立的进程,有自己的main函数.JobTracker是在网络环境中提交及运行MR任务的核心位置. main方法主要代码有两句: 1 //创建jobTracker对象 2 JobTracker tracker = startTracker(new JobConf()); 3 //启动各个服务,包括JT内部一些重要的服务或者线程 4 tracker.offerService(); 一.startTracker(new Jo

A2dp初始化流程源码分析

蓝牙启动的时候,会涉及到各个profile 的启动.这篇文章分析一下,蓝牙中a2dp profile的初始化流程. 我们从AdapterState.java中对于USER_TURN_ON 消息的处理说起: switch(msg.what) { case USER_TURN_ON: notifyAdapterStateChange(BluetoothAdapter.STATE_TURNING_ON); mPendingCommandState.setTurningOn(true); transit

Flume-NG启动过程源码分析(三)(原创)

上一篇文章分析了Flume如何加载配置文件的,动态加载也只是重复运行getConfiguration(). 本篇分析加载配置文件后各个组件是如何运行的? 加载完配置文件订阅者Application类会收到订阅信息执行: @Subscribe public synchronized void handleConfigurationEvent(MaterializedConfiguration conf) { stopAllComponents(); startAllComponents(conf)

【Java】【Flume】Flume-NG启动过程源码分析(一)

从bin/flume 这个shell脚本可以看到Flume的起始于org.apache.flume.node.Application类,这是flume的main函数所在. main方法首先会先解析shell命令,如果指定的配置文件不存在就甩出异常. 根据命令中含有"no-reload-conf"参数,决定采用那种加载配置文件方式:一.没有此参数,会动态加载配置文件,默认每30秒加载一次配置文件,因此可以动态修改配置文件:二.有此参数,则只在启动时加载一次配置文件.实现动态加载功能采用了

【Java】【Flume】Flume-NG启动过程源码分析(二)

本节分析配置文件的解析,即PollingPropertiesFileConfigurationProvider.FileWatcherRunnable.run中的eventBus.post(getConfiguration()).分析getConfiguration()方法.此方法在AbstractConfigurationProvider类中实现了,并且这个类也初始化了三大组件的工厂类:this.sourceFactory = new DefaultSourceFactory();this.s

【Java】【Flume】Flume-NG启动过程源码分析(三)

本篇分析加载配置文件后各个组件是如何运行的? 加载完配置文件订阅者Application类会收到订阅信息执行: @Subscribe public synchronized void handleConfigurationEvent(MaterializedConfiguration conf) { stopAllComponents(); startAllComponents(conf); } MaterializedConfiguration conf就是getConfiguration()

嵌入式linux开发uboot移植(三)——uboot启动过程源码分析

嵌入式linux开发uboot移植(三)--uboot启动过程源码分析 一.uboot启动流程简介 与大多数BootLoader一样,uboot的启动过程分为BL1和BL2两个阶段.BL1阶段通常是开发板的配置等设备初始化代码,需要依赖依赖于SoC体系结构,通常用汇编语言来实现:BL2阶段主要是对外部设备如网卡.Flash等的初始化以及uboot命令集等的自身实现,通常用C语言来实现. 1.BL1阶段 uboot的BL1阶段代码通常放在start.s文件中,用汇编语言实现,其主要代码功能如下:

【Android】应用程序启动过程源码分析

在Android系统中,应用程序是由Activity组成的,因此,应用程序的启动过程实际上就是应用程序中的默认Activity的启动过程,本文将详细分析应用程序框架层的源代码,了解Android应用程序的启动过程. 启动Android应用程序中的Activity的两种情景:其中,在手机屏幕中点击应用程序图标的情景就会引发Android应用程序中的默认Activity的启动,从而把应用程序启动起来.这种启动方式的特点是会启动一个新的进程来加载相应的Activity. 这里,我们以这个例子为例来说明