这篇文章结合4.2.2源码分析点击android桌面app图标启动应用程序的过程.

android的桌面程序(launcher)是android系统启动的第一个应用程序,其他的应用程序安装后,会在launcher上创建一个快捷图标,我们点击桌面上的快捷图标就会启动相应的app,接下来我们就来看看从点击图标到app启动起来的这一过程.

Launcher的源代码工程在packages/apps/Launcher2目录下.

第一步:点击图标,onClick()回调方法被调用,在packages/apps/Launcher2/src/com/android/launcher2/Launcher.java中.

 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()));            boolean success = startActivitySafely(v, intent, tag);//....        } else if (tag instanceof FolderInfo) {         ....        } else if (v == mAllAppsButton) {        .......        }    }

点击app图标,其实是启动app中默认的Activity,例如在清单配置文件中配置我们应用程序的Activity:

                                                          
那么这个MainActivity就是这个应用程序默认的Activity.

第二步:接着看startActivitySafely()方法,还是在Launcher.Java文件中.

boolean startActivitySafely(View v, Intent intent, Object tag) {        boolean success = false;    ....            success = startActivity(v, intent, tag);       .......        return success;    }

第三步:继续调用startActivity()方法,还是在Launcher.Java文件中.

 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);            if (useLaunchAnimation) {//启动的动画,看名字应该是图标放大的动画,这里暂时忽略吧                ActivityOptions opts = ActivityOptions.makeScaleUpAnimation(v, 0, 0,                        v.getMeasuredWidth(), v.getMeasuredHeight());                startActivity(intent, opts.toBundle());            } else {               ....            }            return true;        } catch (SecurityException e) {          ......        }        return false;    }

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);添加这个flag,将在后面决定将这个activity放在哪个task中启动.关于task和这些Intent的flag以及activity的启动模式以后写一篇博客讲解.这里我们只需知道activity启动必须要在一个task中.

第四步:接下来调用到launcher的父类Activity中的startActivity()方法,在frameworks/base/core/java/android/app/Activity.java文件中.

 public void startActivity(Intent intent, Bundle options) {        if (options != null) {            startActivityForResult(intent, -1, options);        } else {           .....        }    }

第五步:继续调用startActivityForResult() ,上面requestCode参数值为-1表示不需要目标activity结束后返回结果,Activity.java文件中.

public void startActivityForResult(Intent intent, int requestCode, 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) {              //不进来            }        } else {           //不进来        }    }

该函数中出现几个新的变量,来看看:

 ① mInstrumentation变量是Instrumentation类型,该对象是在启动应用程序过程中最先创建的,一个应用程序中只有一个Instrumentation对象,每个Activity内部都有一个该对象的引用.Instrumentation可以理解为应用进程的管家,ActivityThread要创建或者暂停某个Activity时,是通过这个"管家"进行的,设置好这个管家的好处是可以统计所有的"开销",开销的信息保存在"管家"那里.
② mMainThread变量是ActivityThread类型,它代表的是应用程序的主线程,一个应用程序中只有一个ActivityThread类,应用程序的入口为该类的main()函数.ActivityThread类在main()方法里实例化的,然后传到activity中.

③ mMainThread.getApplicationThread()返回是ApplicationThread类型的mAppThread对象,ApplicationThread其实是Binder类型.是用来和ActivityManagerService进程间通信的,它是在ActivityThread类中创建的.

④ mToken 也是是Binder类型 它是一个Binder对象的远程接口.每个activity有一个mToken与之相关联.

⑤mParent 也是Activity类型,为null.

第六步:ok,继续调用execStartActivity()方法,在frameworks/base/core/java/android/app/Instrumentation.java文件中.

public ActivityResult execStartActivity(            Context who, IBinder contextThread, IBinder token, Activity target,            Intent intent, int requestCode, Bundle options) {        IApplicationThread whoThread = (IApplicationThread) contextThread;   .....        try {            intent.setAllowFds(false);            intent.migrateExtraStreamToClipData();            int result = ActivityManagerNative.getDefault()                .startActivity(whoThread, intent,                        intent.resolveTypeIfNeeded(who.getContentResolver()),                        token, target != null ? target.mEmbeddedID : null,                        requestCode, 0, null, null, options);          ....        } catch (RemoteException e) {        }        return null;    }

先整理一下参数,根据第五步传过来的值,知道who 就是 activity(launcher)的引用,contextThread是ApplicationThread类型的mAppThread对象,token对应mToken ,target是activity(launcher)的引用,后面requestCode是-1;

这里ActivityManagerNative.getDefault()方法通过binder进程间通信获取了ActivityManagerService系统服务远程接口的引用.关于Binder进程间通信可以参考前面的三篇文章:

Android系统的Binder机制及其native层应用

android应用程序使用Binder实现进程间通信

使用aidl工具快速在应用层实现binder进程间通信

intent.resolveTypeIfNeeded(who.getContentResolver())这个方法是获取这个intent的MIME类型,这里假设没有设置MIME类型  即 在上面的清单文件没有AndroidManifest.xml设置MainActivity的MIME类型,因此,这里返回null。

① target != null ? target.mEmbeddedID : null,这里target不为空,但是mEmbeddedID为空,所以这里也为null.

因此上面接下调用的startActivity(..)的参数就是startActivity(whoThread, intent,  null,token,  null,-1, 0, null, null, options);

第七步:继续调用startActivity()在frameworks/base/core/java/android/app/ActivityManagerNative.java文件中

public int startActivity(IApplicationThread caller, Intent intent,            String resolvedType, IBinder resultTo, String resultWho, int requestCode,            int startFlags, String profileFile,            ParcelFileDescriptor profileFd, Bundle options) throws RemoteException {        Parcel data = Parcel.obtain();        Parcel reply = Parcel.obtain();        data.writeInterfaceToken(IActivityManager.descriptor);        data.writeStrongBinder(caller != null ? caller.asBinder() : null);        intent.writeToParcel(data, 0);        data.writeString(resolvedType);        data.writeStrongBinder(resultTo);        data.writeString(resultWho);        data.writeInt(requestCode);        data.writeInt(startFlags);        data.writeString(profileFile);        if (profileFd != null) {            data.writeInt(1);            profileFd.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驱动,在ActivityManagerService系统服务端 onTransact(...)就会被调用到

public boolean onTransact(int code, Parcel data, Parcel reply, int flags)            throws RemoteException {        switch (code) {        case START_ACTIVITY_TRANSACTION:        {            data.enforceInterface(IActivityManager.descriptor);            IBinder b = data.readStrongBinder();            IApplicationThread app = ApplicationThreadNative.asInterface(b);            Intent intent = Intent.CREATOR.createFromParcel(data);            String resolvedType = data.readString();            IBinder resultTo = data.readStrongBinder();            String resultWho = data.readString();            int requestCode = data.readInt();            int startFlags = data.readInt();            String profileFile = data.readString();            ParcelFileDescriptor profileFd = data.readInt() != 0                    ? data.readFileDescriptor() : null;            Bundle options = data.readInt() != 0                    ? Bundle.CREATOR.createFromParcel(data) : null;            int result = startActivity(app, intent, resolvedType,                    resultTo, resultWho, requestCode, startFlags,                    profileFile, profileFd, options);            reply.writeNoException();            reply.writeInt(result);            return true;        }

上面startActivity(...)消息就会发送到ActivityManagerService中了,这里整理一下参数:app为IApplicationThread,resolvedType为null,resultTo为Binder类型(mToken),resultWho为null,requestCode为-1,startFlags为0,profileFile为null,profileFd为null.因此接下startActivity(app, intent, null, resultTo, null, -1, 0, null, null, options).

第八步:调用startActivity(),frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中

 public final int startActivity(IApplicationThread caller,            Intent intent, String resolvedType, IBinder resultTo,            String resultWho, int requestCode, int startFlags,            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {        return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());    }

第九步:接着调用startActivityAsUser().在ActivityManagerService.java文件中

 public final int startActivityAsUser(IApplicationThread caller,            Intent intent, String resolvedType, IBinder resultTo,            String resultWho, int requestCode, int startFlags,            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {        enforceNotIsolatedCaller("startActivity");        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,                false, true, "startActivity", null);        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,                null, null, options, userId);    }

第十步:接着调用startActivityMayWait().在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中

 final int startActivityMayWait(IApplicationThread caller, int callingUid,            Intent intent, String resolvedType, IBinder resultTo,            String resultWho, int requestCode, int startFlags, String profileFile,            ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config,            Bundle options, int userId) {     .....        boolean componentSpecified = intent.getComponent() != null;//这里为true        // Don't modify the client's object!        intent = new Intent(intent);        // Collect information about the target of the Intent.        ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,                profileFile, profileFd, userId);        synchronized (mService) {            int callingPid;            if (callingUid >= 0) {             ....            } else if (caller == null) {             ....            } else {                callingPid = callingUid = -1;//走这里            }            mConfigWillChange = config != null                    && mService.mConfiguration.diff(config) != 0;//为false          ....            if (mMainStack && aInfo != null &&                    (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {//最后条件不满足             ....            }            int res = startActivityLocked(caller, intent, resolvedType,                    aInfo, resultTo, resultWho, requestCode, callingPid, callingUid,                    startFlags, options, componentSpecified, null);                        if (mConfigWillChange && mMainStack) {            ....//不进来            }            if (outResult != null) {               .....//不进来            }            return res;        }    }
参数outResult和config均为null,此外,表达式(aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0为false,因此,这里忽略了无关代码。resolveActivity(intent, resolvedType, startFlags, profileFile, profileFd, userId)方法对参数intent的内容进行解析,得到目标activity的相关信息,保存在aInfo变量中.

ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,            String profileFile, ParcelFileDescriptor profileFd, int userId) {        // Collect information about the target of the Intent.        ActivityInfo aInfo;        try {            ResolveInfo rInfo =                AppGlobals.getPackageManager().resolveIntent(                        intent, resolvedType,                        PackageManager.MATCH_DEFAULT_ONLY                                    | ActivityManagerService.STOCK_PM_FLAGS, userId);            aInfo = rInfo != null ? rInfo.activityInfo : null;        } catch (RemoteException e) {            aInfo = null;        }        if (aInfo != null) {      ....            intent.setComponent(new ComponentName(                    aInfo.applicationInfo.packageName, aInfo.name));....        }        return aInfo;    }

 此外,函数开始的地方调用intent.getComponent()函数的返回值不为null,因此,这里的componentSpecified变量为true.整理一下接下调用的参数

startActivityLocked(caller,intent,null,aInfo,resultTo,null,-1,-1,-1,0,options,true,null);

第十一步:接着调用startActivityLocked().在ActivityStack.java文件中

final int startActivityLocked(IApplicationThread caller,            Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,            String resultWho, int requestCode,            int callingPid, int callingUid, int startFlags, Bundle options,            boolean componentSpecified, ActivityRecord[] outActivity) {        int err = ActivityManager.START_SUCCESS;        ProcessRecord callerApp = null;        if (caller != null) {            callerApp = mService.getRecordForAppLocked(caller);            if (callerApp != null) {                callingPid = callerApp.pid;                callingUid = callerApp.info.uid;            } else {             ....            }        }        if (err == ActivityManager.START_SUCCESS) {            final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;            Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)                    + "} from pid " + (callerApp != null ? callerApp.pid : callingPid));        }        ActivityRecord sourceRecord = null;        ActivityRecord resultRecord = null;        if (resultTo != null) {            int index = indexOfTokenLocked(resultTo);            if (DEBUG_RESULTS) Slog.v(                TAG, "Will send result to " + resultTo + " (index " + index + ")");            if (index >= 0) {                sourceRecord = mHistory.get(index);                if (requestCode >= 0 && !sourceRecord.finishing) {                    ....                }            }        }        int launchFlags = intent.getFlags();//第三步 addFlag()设置的 NEW_TASK,        if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0                && sourceRecord != null) {           .....        }        if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {           ...        }        if (err == ActivityManager.START_SUCCESS && aInfo == null) {          ...        }        if (err != ActivityManager.START_SUCCESS) {           ....        }  ....        ActivityRecord r = new ActivityRecord(mService, this, callerApp, callingUid,                intent, resolvedType, aInfo, mService.mConfiguration,                resultRecord, resultWho, requestCode, componentSpecified);        if (outActivity != null) {           ...        }      ......        err = startActivityUncheckedLocked(r, sourceRecord,                startFlags, true, options);        ....        return err;    }

从传进来的参数caller得到调用者的进程信息,并保存在callerApp变量中,这里就是Launcher应用程序的进程信息了.前面说过,参数resultTo是Launcher这个Activity对应的一个Binder对象,通过它可以获得Launcher这个Activity的相关信息,保存在sourceRecord变量中。再接下来,创建即将要启动的Activity的相关信息,并保存在r变量中:在frameworks/base/services/java/com/android/server/am/ActivityRecord.java文件中

  ActivityRecord(ActivityManagerService _service, ActivityStack _stack, ProcessRecord _caller,            int _launchedFromUid, Intent _intent, String _resolvedType,            ActivityInfo aInfo, Configuration _configuration,            ActivityRecord _resultTo, String _resultWho, int _reqCode,            boolean _componentSpecified) {        service = _service;        stack = _stack;        appToken = new Token(this);//第七步 ④mToken 类型和这个类型一样 这里的appToken是与将要启动的activity相关的,④mToken是launcher中的        info = aInfo;        launchedFromUid = _launchedFromUid;        userId = UserHandle.getUserId(aInfo.applicationInfo.uid);        intent = _intent;        shortComponentName = _intent.getComponent().flattenToShortString();        resolvedType = _resolvedType;        componentSpecified = _componentSpecified;        configuration = _configuration;        resultTo = _resultTo;//传进来是null        resultWho = _resultWho;        requestCode = _reqCode;        state = ActivityState.INITIALIZING;        frontOfTask = false;        launchFailed = false;        stopped = false;        delayedResume = false;        finishing = false;        configDestroy = false;        keysPaused = false;        inHistory = false;        visible = true;        waitingVisible = false;        nowVisible = false;        thumbnailNeeded = false;        idle = false;        hasBeenLaunched = false;        // This starts out true, since the initial state of an activity        // is that we have everything, and we shouldn't never consider it        // lacking in state to be removed if it dies.        haveState = true;

上面的appToken变量很重要

第十二步:调用startActivityUncheckedLocked(),ActivityStack.java文件中

final int startActivityUncheckedLocked(ActivityRecord r,            ActivityRecord sourceRecord, int startFlags, boolean doResume,            Bundle options) {        final Intent intent = r.intent;        final int callingUid = r.launchedFromUid;        int launchFlags = intent.getFlags();        // We'll invoke onUserLeaving before onPause only if the launching        // activity did not explicitly state that this is an automated launch.        mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;  ....        // If the caller has asked not to resume at this point, we make note        // of this in the record so that we can skip it when trying to find        // the top running activity.        if (!doResume) {         ...        }        ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP)                != 0 ? r : null;        // If the onlyIfNeeded flag is set, then we can do this if the activity        // being launched is the same as the one making the call...  or, as        // a special case, if we do not know the caller then we count the        // current top activity as the caller.        if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {         ....        }        if (sourceRecord == null) {            ...        } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {         ...        } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE           ...        }        if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {         ....        }        boolean addingToTask = false;        boolean movedHome = false;        TaskRecord reuseTask = null;        if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&                (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {            // If bring to front is requested, and no result is requested, and            // we can find a task that was started with this same            // component, then instead of launching bring that one to the front.            if (r.resultTo == null) {                // See if there is a task to bring to the front.  If this is                // a SINGLE_INSTANCE activity, there can be one and only one                // instance of it in the history, and it is always in its own                // unique task, so we do a special search.                ActivityRecord taskTop = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE                        ? findTaskLocked(intent, r.info)                        : findActivityLocked(intent, r.info);                if (taskTop != null) {                  ....            }        }.....        if (r.packageName != null) {            // If the activity being launched is the same as the one currently            // at the top, then we need to check if it should only be launched            // once.            ActivityRecord top = topRunningNonDelayedActivityLocked(notTop);            if (top != null && r.resultTo == null) {                if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {                    ....                }            }        } else {        ....        }        boolean newTask = false;        boolean keepCurTransition = false;        // Should this be considered a new task?        if (r.resultTo == null && !addingToTask                && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {            if (reuseTask == null) {                // todo: should do better management of integers.                mService.mCurTask++;                if (mService.mCurTask <= 0) {                    mService.mCurTask = 1;                }                r.setTask(new TaskRecord(mService.mCurTask, r.info, intent), null, true);                if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r                        + " in new task " + r.task);            } else {              ....            }            newTask = true;            if (!movedHome) {                moveHomeToFrontFromLaunchLocked(launchFlags);            }                    } else if (sourceRecord != null) {     ....        } else {        ....        }        mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,                intent, r.getUriPermissionsLocked());        if (newTask) {            EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);        }        logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);        startActivityLocked(r, newTask, doResume, keepCurTransition, options);        return ActivityManager.START_SUCCESS;    }
这个函数的主要作用是是判断是否需要新建一个task来启动activity,这与launchFlag和launchMode有关。由于r.launchMode的值不为ActivityInfo.LAUNCH_SINGLE_INSTANCE,因此,它通过findTaskLocked函数来查找存不存这样的Task,目标activity所在应用是第一次启动,所以这里返回的结果是null,即taskTop为null.接着判断 当前在堆栈顶端的Activity是否就是即将要启动的Activity, 现在处理堆栈顶端的Activity是Launcher,与我们即将要启动的MainActivity不是同一个Activity.因此需要创建一个新的Task来启动这个Activity.

第十三步:调用startActivityLocked();ActivityStack.java文件中  参数分别为r,true,true,false,options

 private final void startActivityLocked(ActivityRecord r, boolean newTask,            boolean doResume, boolean keepCurTransition, Bundle options) {        final int NH = mHistory.size();        int addPos = -1;                if (!newTask) {          .....        }        // Place a new activity at top of stack, so it is next to interact        // with the user.        if (addPos < 0) {            addPos = NH;        }                // If we are not placing the new activity frontmost, we do not want        // to deliver the onUserLeaving callback to the actual frontmost        // activity        if (addPos < NH) {           ...        }   .....        mHistory.add(addPos, r);        r.putInHistory();        r.frontOfTask = newTask;        if (NH > 0) {            // We want to show the starting preview window if we are            // switching to a new task, or the next activity's process is            // not currently running.            boolean showStartingIcon = newTask;            ProcessRecord proc = r.app;            if (proc == null) {                proc = mService.mProcessNames.get(r.processName, r.info.applicationInfo.uid);            }            if (proc == null || proc.thread == null) {                showStartingIcon = true;            }            if (DEBUG_TRANSITION) Slog.v(TAG,                    "Prepare open transition: starting " + r);            if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {                mService.mWindowManager.prepareAppTransition(                        WindowManagerPolicy.TRANSIT_NONE, keepCurTransition);                mNoAnimActivities.add(r);            } else {                mService.mWindowManager.prepareAppTransition(newTask                        ? WindowManagerPolicy.TRANSIT_TASK_OPEN                        : WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN, keepCurTransition);                mNoAnimActivities.remove(r);            }            r.updateOptionsLocked(options);            mService.mWindowManager.addAppToken(addPos, r.userId, r.appToken,                    r.task.taskId, r.info.screenOrientation, r.fullscreen,                    (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0,                    r.info.flags);            boolean doShow = true;            if (newTask) {                // Even though this activity is starting fresh, we still need                // to reset it to make sure we apply affinities to move any                // existing activities from other tasks in to it.                // If the caller has requested that the target task be                // reset, then do so.                if ((r.intent.getFlags()                        &Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {                    resetTaskIfNeededLocked(r, r);                    doShow = topRunningNonDelayedActivityLocked(null) == r;                }            }            if (SHOW_APP_STARTING_PREVIEW && doShow) {                // Figure out if we are transitioning from another activity that is                // "has the same starting icon" as the next one.  This allows the                // window manager to keep the previous window it had previously                // created, if it still had one.                ActivityRecord prev = mResumedActivity;                if (prev != null) {                    // We don't want to reuse the previous starting preview if:                    // (1) The current activity is in a different task.                    if (prev.task != r.task) prev = null;                    // (2) The current activity is already displayed.                    else if (prev.nowVisible) prev = null;                }                mService.mWindowManager.setAppStartingWindow(                        r.appToken, r.packageName, r.theme,                        mService.compatibilityInfoForPackageLocked(                                r.info.applicationInfo), r.nonLocalizedLabel,                        r.labelRes, r.icon, r.windowFlags,                        prev != null ? prev.appToken : null, showStartingIcon);            }        } else {            // If this is the first activity, don't do any fancy animations,            // because there is nothing for it to animate on top of.            mService.mWindowManager.addAppToken(addPos, r.userId, r.appToken,                    r.task.taskId, r.info.screenOrientation, r.fullscreen,                    (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0,                    r.info.flags);            ActivityOptions.abort(options);        }        if (VALIDATE_TOKENS) {          ..        }        if (doResume) {            resumeTopActivityLocked(null);        }    }
这个函数将要启动启动的activity放入到序列mHistory中,然后做task切换,因为launcher跟目标activity不在同一任务中.

第十四步:resumeTopActivityLocked()继续,ActivityStack.java文件中,参数为null:

 final boolean resumeTopActivityLocked(ActivityRecord prev) {        return resumeTopActivityLocked(prev, null);    }

第十五步:resumeTopActivityLocked();继续,ActivityStack.java文件中,参数为nul,nulll:

final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {        // Find the first activity that is not finishing.        ActivityRecord next = topRunningActivityLocked(null);//        // Remember how we'll process this pause/resume situation, and ensure        // that the state is reset however we wind up proceeding.        final boolean userLeaving = mUserLeaving;        mUserLeaving = false;        if (next == null) {         .....        }        next.delayedResume = false;                // If the top activity is the resumed one, nothing to do.        if (mResumedActivity == next && next.state == ActivityState.RESUMED) {        .....        }        // 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.mSleeping || mService.mShuttingDown)                && mLastPausedActivity == next                && (next.state == ActivityState.PAUSED                    || next.state == ActivityState.STOPPED                    || next.state == ActivityState.STOPPING)) {  .....        }        // Make sure that the user who owns this activity is started.  If not,        // we will just leave it as is because someone should be bringing        // another user's activities to the top of the stack.        if (mService.mStartedUsers.get(next.userId) == null) {       ...        }        // The activity may be waiting for stop, but that is no longer        // appropriate for it.        mStoppingActivities.remove(next);        mGoingToSleepActivities.remove(next);        next.sleeping = false;        mWaitingVisibleActivities.remove(next);        next.updateOptionsLocked(options);        if (DEBUG_SWITCH) Slog.v(TAG, "Resuming " + next);        // If we are currently pausing an activity, then don't do anything        // until that is done.        if (mPausingActivity != null) {      .....        }        // Okay we are now going to start a switch, to 'next'.  We may first        // have to pause the current activity, but this is an important point        // where we have decided to go to 'next' so keep track of that.        // XXX "App Redirected" dialog is getting too many false positives        // at this point, so turn off for now.        if (false) {         ...        }                // We need to start pausing the current activity so the top one        // can be resumed...        if (mResumedActivity != null) {            if (next.app != null && next.app.thread != null) {                ...            }          startPausingLocked(userLeaving, false);            return true;        }      .....        return true;    }

函数先通过调用topRunningActivityLocked函数获得堆栈顶端的Activity,这里就是要启动的MainActivity了(第十三步添加进去的),保存在next变量中。 接下来把mUserLeaving的保存在本地变量userLeaving中,然后重新设置为false,在上面mUserLeaving的值为true,因此,这里的userLeaving为true。这里的mResumedActivity为Launcher,因为Launcher是当前正被执行的Activity。我们知道启动一个新的activity首先要暂停正在运行的activity.

第十六步:startPausingLocked(),ActivityStack.java文件中,参数为true,false:

private final void startPausingLocked(boolean userLeaving, boolean uiSleeping) {        if (mPausingActivity != null) {      ......        }        ActivityRecord prev = mResumedActivity;        if (prev == null) {     .....        }     ....        mResumedActivity = null;        mPausingActivity = prev;        mLastPausedActivity = prev;        prev.state = ActivityState.PAUSING;        prev.task.touchActiveTime();        prev.updateThumbnail(screenshotActivities(prev), null);        mService.updateCpuStats();                if (prev.app != null && prev.app.thread != null) {            if (DEBUG_PAUSE) Slog.v(TAG, "Enqueueing pending pause: " + prev);            try {                EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,                        prev.userId, System.identityHashCode(prev),                        prev.shortComponentName);            prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,                        userLeaving, prev.configChangeFlags);                if (mMainStack) {                    mService.updateUsageStats(prev, false);                }            } catch (Exception e) {                // Ignore exception, if process died other code will cleanup.                Slog.w(TAG, "Exception thrown during pause", e);                mPausingActivity = null;                mLastPausedActivity = null;            }        } else {           ...        }        // If we are not going to sleep, we want to ensure the device is        // awake until the next activity is started.        if (!mService.mSleeping && !mService.mShuttingDown) {            mLaunchingActivity.acquire();            if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {                // To be safe, don't allow the wake lock to be held for too long.                Message msg = mHandler.obtainMessage(LAUNCH_TIMEOUT_MSG);                mHandler.sendMessageDelayed(msg, LAUNCH_TIMEOUT);            }        }      ...    }

这个函数对一些变量进行赋值,后面的需要用到.然后就去暂停launcher activty

第十七步:schedulePauseActivity();frameworks/base/core/java/android/app/ApplicationThreadNative.java文件中,

这里又是Binder进程间通信了.参数token就是第五步mToken(与launcher这个activity相关的),其他几个参数false,true,false

public final void schedulePauseActivity(IBinder token, boolean finished,            boolean userLeaving, int configChanges) 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);        mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null,                IBinder.FLAG_ONEWAY);        data.recycle();    }

经过Binder驱动

public boolean onTransact(int code, Parcel data, Parcel reply, int flags)            throws RemoteException {        switch (code) {        case SCHEDULE_PAUSE_ACTIVITY_TRANSACTION:        {            data.enforceInterface(IApplicationThread.descriptor);            IBinder b = data.readStrongBinder();            boolean finished = data.readInt() != 0;            boolean userLeaving = data.readInt() != 0;            int configChanges = data.readInt();            schedulePauseActivity(b, finished, userLeaving, configChanges);//这里就到launcher  ActivityThread中去了            return true;        }
第十八步 : schedulePauseActivity()  在frameworks/base/core/java/android/app/ActivityThread.java中
 public final void schedulePauseActivity(IBinder token, boolean finished,                boolean userLeaving, int configChanges) {            queueOrSendMessage(                    finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,//这里是PAUSE_ACTIVITY                    token,                    (userLeaving ? 1 : 0),                    configChanges);        }
第十九步 : queueOrSendMessage(),ActivityThread.java中
private void queueOrSendMessage(int what, Object obj, int arg1, int arg2) {        synchronized (this) {            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;            mH.sendMessage(msg);        }    }

mH是Handler类型,ActivityThread.java成员变量,这里将相关数据封装消息发送到主线程的消息队列.

第二十步:handleMessage(),ActivityThread.java中

  case PAUSE_ACTIVITY:                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");                    handlePauseActivity((IBinder)msg.obj, false, msg.arg1 != 0, msg.arg2);//??                    maybeSnapshot();                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                    break;
第二十一步 :: 继续 handlePauseActivity() ,在ActivityThread.java中
 private void handlePauseActivity(IBinder token, boolean finished,            boolean userLeaving, int configChanges) {        ActivityClientRecord r = mActivities.get(token);//        if (r != null) {            //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);            if (userLeaving) {//这里为true                performUserLeavingActivity(r);//            }            r.activity.mConfigChangeFlags |= configChanges;            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.            try {                ActivityManagerNative.getDefault().activityPaused(token);//            } catch (RemoteException ex) {            }        }    }

首先performUserLeavingActivity 会导致onUserInteraction(),onUserLeaveHint()会先后被调用,这两个回调平时我们应该没怎么重写.

第二十二步:先调用performPauseActivity(),ActivityThread.java中

final Bundle performPauseActivity(IBinder token, boolean finished,            boolean saveState) {        ActivityClientRecord r = mActivities.get(token);        return r != null ? performPauseActivity(r, finished, saveState) : null;    }
第二十三步:performPauseActivity() ,ActivityThread.java中
final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,            boolean saveState) {        if (r.paused) {       .....        }        Bundle state = null;        if (finished) {          ...        }        try {            // Next have the activity save its current state and managed dialogs...            if (!r.activity.mFinished && saveState) {                state = new Bundle();                state.setAllowFds(false);                mInstrumentation.callActivityOnSaveInstanceState(r.activity, state);//                r.state = state;            }            // Now we are idle.            r.activity.mCalled = false;            mInstrumentation.callActivityOnPause(r.activity);//     ....        } catch (SuperNotCalledException e) {            throw e;        } catch (Exception e) {            if (!mInstrumentation.onException(r.activity, e)) {                throw new RuntimeException(                        "Unable to pause activity "                        + r.intent.getComponent().toShortString()                        + ": " + e.toString(), e);            }        }        r.paused = true;.....        return state;    }

OnSaveInstanceState()可能被回调(targetSdkVersion

第二十四步:接着看第二十一步activityPaused(),frameworks/base/core/java/android/app/ActivityManagerNative.java中.

launcher执行完暂停之后,通过Binder进程间通信,告诉ActivityManagerService可以启动目标Activity.

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驱动
 case ACTIVITY_PAUSED_TRANSACTION: {            data.enforceInterface(IActivityManager.descriptor);            IBinder token = data.readStrongBinder();            activityPaused(token);//            reply.writeNoException();            return true;        }

第二十五步:activityPaused() ,frameworks/base/services/java/com/android/server/am/ActivityManagerService.java中

 public final void activityPaused(IBinder token) {        final long origId = Binder.clearCallingIdentity();        mMainStack.activityPaused(token, false);//        Binder.restoreCallingIdentity(origId);    }
第二十六步:activityPaused(),frameworks/base/services/java/com/android/server/am/ActivityStack.java中
final void activityPaused(IBinder token, boolean timeout) {      ...        ActivityRecord r = null;        synchronized (mService) {            int index = indexOfTokenLocked(token);            if (index >= 0) {                r = mHistory.get(index);                mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);                if (mPausingActivity == r) {//这里在第十六步中设置的,mPausingActivity就是launcher对应的                    if (DEBUG_STATES) Slog.v(TAG, "Moving to PAUSED: " + r                            + (timeout ? " (due to timeout)" : " (pause complete)"));                    r.state = ActivityState.PAUSED;                    completePauseLocked();//                } else {                    ....                }            }        }    }
第二十七步:completePauseLocked() ,ActivityStack.java
 private final void completePauseLocked() {        ActivityRecord prev = mPausingActivity;    ....        if (prev != null) {          ....            mPausingActivity = null;        }        if (!mService.isSleeping()) {            resumeTopActivityLocked(prev);//        } else {           .....            }        }     ...    }

函数首先把mPausingActivity变量清空,因为现在不需要它了,然后调用resumeTopActivityLokced进一步操作,它传入的参数即为代表Launcher这个Activity的ActivityRecord

第二十八步:resumeTopActivityLocked(),ActivityStack.java中 

 final boolean resumeTopActivityLocked(ActivityRecord prev) {        return resumeTopActivityLocked(prev, null);    }
第二十九步: resumeTopActivityLocked() ,ActivityStack.java中 .

final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {     ...        ActivityRecord next = topRunningActivityLocked(null);....        final boolean userLeaving = mUserLeaving;        mUserLeaving = false;        if (next == null) {     ...        }        next.delayedResume = false;    ....        if (mResumedActivity == next && next.state == ActivityState.RESUMED) {        ...            return false;        }.....        if ((mService.mSleeping || mService.mShuttingDown)            .....        }        // We need to start pausing the current activity so the top one        // can be resumed...        if (mResumedActivity != null) {         .....            return true;        }....        if (next.app != null && next.app.thread != null) {          ...        } else {           ...            startSpecificActivityLocked(next, true, true);//---------------------------------        }        return true;    }

我们知道,当前在堆栈顶端的Activity为我们即将要启动的MainActivity,这里通过调用topRunningActivityLocked将它取回来,保存在next变量中。之前最后一个Resumed状态的Activity,即Launcher,到了这里已经处于Paused状态了(第二十六步设置的),因此,mResumedActivity为null。最后一个处于Paused状态的Activity为Launcher,因此,这里的mLastPausedActivity就为Launcher(第十六步设置的)。前面我们为MainActivity创建ActivityRecord后,它的app域一直保持为null。最终调用startSpecificActivityLocked进行下一步操作。

第三十步:startSpecificActivityLocked(),ActivityStack.java中

 private final 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);    ....               if (app != null && app.thread != null) {            try {                app.addPackage(r.info.packageName);                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);    }    

注意,这里由于是第一次启动应用程序的Activity,所以下面语句:取回来的app为null。在Activity应用程序中的AndroidManifest.xml配置文件中,我们没有指定Application标签的process属性,系统就会默认使用package的名称。函数最终执行ActivityManagerService.startProcessLocked函数进行下一步操作。
第三十一步:startProcessLocked(), frameworks/base/services/java/com/android/server/am/ActivityManagerService.java中

ProcessRecord startProcessLocked(String processName,            ApplicationInfo info, boolean knownToBeDead, int intentFlags,            String hostingType, ComponentName hostingName, boolean allowWhileBooting,            boolean isolated) {        ProcessRecord app;        if (!isolated) {            app = getProcessRecordLocked(processName, info.uid);        } else {         ...        }       ....        String hostingNameStr = hostingName != null                ? hostingName.flattenToShortString() : null;        ...        if (app == null) {            app = newProcessRecordLocked(null, info, processName, isolated);    ....            mProcessNames.put(processName, app.uid, app);        ..        } else {            // If this is a new package in the process, add the package to the list            app.addPackage(info.packageName);        }        // If the system is not ready yet, then hold off on starting this        // process until it is.      .....        startProcessLocked(app, hostingType, hostingNameStr);        return (app.pid != 0) ? app : null;    }

 这里再次检查是否已经有以process + uid命名的进程存在,在我们这个情景中,返回值app为null,因此,后面会创建一个ProcessRecord,并存保存在成员变量mProcessNames中,最后,调用另一个startProcessLocked函数进一步操作:

第三十二步:startProcessLocked(),ActivityManagerService.java中

 private final void startProcessLocked(ProcessRecord app,            String hostingType, String hostingNameStr) {       .....        try {            int uid = app.uid;            int[] gids = null;            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;            if (!app.isolated) {                int[] permGids = null;                try {                    final PackageManager pm = mContext.getPackageManager();                    permGids = pm.getPackageGids(app.info.packageName);                    if (Environment.isExternalStorageEmulated()) {                        if (pm.checkPermission(                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,                                app.info.packageName) == PERMISSION_GRANTED) {                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;                        } else {                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;                        }                    }                } catch (PackageManager.NameNotFoundException e) {                    Slog.w(TAG, "Unable to retrieve gids", e);                }             .......            // Start the process.  It will either succeed and return a result containing            // the PID of the new process, or else throw a RuntimeException.            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",                    app.processName, uid, uid, gids, debugFlags, mountExternal,                    app.info.targetSdkVersion, null, null);         .....            }        } catch (RuntimeException e) {          ..        }    }
这里主要是调用Process.start接口来创建一个新的进程,新的进程会导入android.app.ActivityThread类,并且执行它的main函数,这就是为什么我们前面说每一个应用程序都有一个ActivityThread实例来对应的原因。

第三十三步:main(),frameworks/base/core/java/android/app/ActivityThread.java

 public static void main(String[] args) {    ...        Looper.prepareMainLooper();        ActivityThread thread = new ActivityThread();        thread.attach(false);        if (sMainThreadHandler == null) {            sMainThreadHandler = thread.getHandler();        }        AsyncTask.init();        if (false) {            Looper.myLooper().setMessageLogging(new                    LogPrinter(Log.DEBUG, "ActivityThread"));        }        Looper.loop();        throw new RuntimeException("Main thread loop unexpectedly exited");    }}
 这个函数在进程中创建一个ActivityThread实例(对应第五步②),然后调用它的attach函数,接着就进入消息循环了,直到最后进程退出。

第三十四步:attach(),在ActivityThread.java中

private void attach(boolean system) {        sThreadLocal.set(this);        mSystemThread = system;        if (!system) {            ViewRootImpl.addFirstDrawHandler(new Runnable() {                public void run() {                    ensureJitEnabled();                }            });            android.ddm.DdmHandleAppName.setAppName("",                                                    UserHandle.myUserId());            RuntimeInit.setApplicationObject(mAppThread.asBinder());            IActivityManager mgr = ActivityManagerNative.getDefault();            try {                mgr.attachApplication(mAppThread);            } catch (RemoteException ex) {                // Ignore            }        } else {           .....        }......    }

函数attach最终调用了ActivityManagerService的远程接口ActivityManagerProxy的attachApplication函数,传入的参数是mAppThread,这是一个ApplicationThread类型的Binder对象,它的作用是用来进行进程间通信的。final ApplicationThread mAppThread = new ApplicationThread();ActivityThread类的成员变量(对应第五步③).

第三十五步:attach(),在ActivityManagerNative.java中

 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驱动
 case ATTACH_APPLICATION_TRANSACTION: {            data.enforceInterface(IActivityManager.descriptor);            IApplicationThread app = ApplicationThreadNative.asInterface(                    data.readStrongBinder());            if (app != null) {                attachApplication(app);            }            reply.writeNoException();            return true;        }

第三十六步 :attachApplication(),在ActivityManagerService.java中

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

第四三十七步:attachApplication(),在ActivityManagerService.java中

private final boolean attachApplicationLocked(IApplicationThread thread,            int pid) {        // Find the application record that is being attached...  either via        // the pid if we are running in multiple processes, or just pull the        // next app record if we are emulating process with anonymous threads.        ProcessRecord app;        if (pid != MY_PID && pid >= 0) {            synchronized (mPidsSelfLocked) {                app = mPidsSelfLocked.get(pid);            }        } else {            app = null;        }        if (app == null) {           .....        }        // If this application record is still attached to a previous        // process, clean it up now.        if (app.thread != null) {           .....        }        // Tell the process all about itself.        if (localLOGV) Slog.v(                TAG, "Binding process pid " + pid + " to record " + app);.......        app.thread = thread;    ....        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;        if (!normalMode) {            Slog.i(TAG, "Launching preboot mode app: " + app);        }        if (localLOGV) Slog.v(            TAG, "New app record " + app            + " thread=" + thread.asBinder() + " pid=" + pid);        try {          .....            thread.bindApplication(processName, appInfo, providers,                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,                    app.instrumentationArguments, app.instrumentationWatcher, testMode,                    enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),                    mCoreSettingsObserver.getCoreSettingsLocked());         .....        } catch (Exception e) {       .....        }......        // See if the top visible activity is waiting to run in this process...        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);        if (hr != null && normalMode) {            if (hr.app == null && app.uid == hr.info.applicationInfo.uid                    && processName.equals(hr.processName)) {                try {                    if (mHeadless) {                        ....                    } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {                        didSomething = true;                    }                } catch (Exception e) {                  ...                }            } else {                ...            }        }       .......        return true;    }
  在前面( 第三十一步 ),已经创建了一个ProcessRecord,这里首先通过pid将它取回来,放在app变量中,然后对app的其它成员进行初始化.这里先后调用两个方法,bindApplication(),realStartActivityLocked()分别来看看。都是是通过Binder进程间通信.

第三十八步:bindApplication(),在ApplicationThreadNative.java中.

public final void bindApplication(String packageName, ApplicationInfo info,            List providers, ComponentName testName, String profileName,            ParcelFileDescriptor profileFd, boolean autoStopProfiler, Bundle testArgs,            IInstrumentationWatcher testWatcher, int debugMode, boolean openGlTrace,            boolean restrictedBackupMode, boolean persistent,            Configuration config, CompatibilityInfo compatInfo,            Map services, Bundle coreSettings) throws RemoteException {        Parcel data = Parcel.obtain();        data.writeInterfaceToken(IApplicationThread.descriptor);        data.writeString(packageName);        info.writeToParcel(data, 0);        data.writeTypedList(providers);        if (testName == null) {            data.writeInt(0);        } else {            data.writeInt(1);            testName.writeToParcel(data, 0);        }        data.writeString(profileName);        if (profileFd != null) {            data.writeInt(1);            profileFd.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);        } else {            data.writeInt(0);        }        data.writeInt(autoStopProfiler ? 1 : 0);        data.writeBundle(testArgs);        data.writeStrongInterface(testWatcher);        data.writeInt(debugMode);        data.writeInt(openGlTrace ? 1 : 0);        data.writeInt(restrictedBackupMode ? 1 : 0);        data.writeInt(persistent ? 1 : 0);        config.writeToParcel(data, 0);        compatInfo.writeToParcel(data, 0);        data.writeMap(services);        data.writeBundle(coreSettings);        mRemote.transact(BIND_APPLICATION_TRANSACTION, data, null,                IBinder.FLAG_ONEWAY);        data.recycle();    }
经过Binder驱动
case BIND_APPLICATION_TRANSACTION:        {            data.enforceInterface(IApplicationThread.descriptor);            String packageName = data.readString();            ApplicationInfo info =                ApplicationInfo.CREATOR.createFromParcel(data);            List providers =                data.createTypedArrayList(ProviderInfo.CREATOR);            ComponentName testName = (data.readInt() != 0)                ? new ComponentName(data) : null;            String profileName = data.readString();            ParcelFileDescriptor profileFd = data.readInt() != 0                    ? data.readFileDescriptor() : null;            boolean autoStopProfiler = data.readInt() != 0;            Bundle testArgs = data.readBundle();            IBinder binder = data.readStrongBinder();            IInstrumentationWatcher testWatcher = IInstrumentationWatcher.Stub.asInterface(binder);            int testMode = data.readInt();            boolean openGlTrace = data.readInt() != 0;            boolean restrictedBackupMode = (data.readInt() != 0);            boolean persistent = (data.readInt() != 0);            Configuration config = Configuration.CREATOR.createFromParcel(data);            CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);            HashMap services = data.readHashMap(null);            Bundle coreSettings = data.readBundle();            bindApplication(packageName, info,                            providers, testName, profileName, profileFd, autoStopProfiler,                            testArgs, testWatcher, testMode, openGlTrace, restrictedBackupMode,                            persistent, config, compatInfo, services, coreSettings);            return true;        }

第三十九步 :bindApplication(),在ActivityThread.java中.这里已经到目标activity所在进程来了

public final void bindApplication(String processName,                ApplicationInfo appInfo, List providers,                ComponentName instrumentationName, String profileFile,                ParcelFileDescriptor profileFd, boolean autoStopProfiler,                Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher,                int debugMode, boolean enableOpenGlTrace, boolean isRestrictedBackupMode,                boolean persistent, Configuration config, CompatibilityInfo compatInfo,                Map services, Bundle coreSettings) {            if (services != null) {                // Setup the service cache in the ServiceManager                ServiceManager.initServiceCache(services);            }            setCoreSettings(coreSettings);            AppBindData data = new AppBindData();            data.processName = processName;            data.appInfo = appInfo;            data.providers = providers;            data.instrumentationName = instrumentationName;            data.instrumentationArgs = instrumentationArgs;            data.instrumentationWatcher = instrumentationWatcher;            data.debugMode = debugMode;            data.enableOpenGlTrace = enableOpenGlTrace;            data.restrictedBackupMode = isRestrictedBackupMode;            data.persistent = persistent;            data.config = config;            data.compatInfo = compatInfo;            data.initProfileFile = profileFile;            data.initProfileFd = profileFd;            data.initAutoStopProfiler = false;            queueOrSendMessage(H.BIND_APPLICATION, data);        }

第四十步 :queueOrSendMessage(),在ActivityThread.java中

private void queueOrSendMessage(int what, Object obj) {        queueOrSendMessage(what, obj, 0, 0);    }    private void queueOrSendMessage(int what, Object obj, int arg1, int arg2) {        synchronized (this) {            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;            mH.sendMessage(msg);        }    }

第四十一步 :handleMessage(),在ActivityThread.java中

case BIND_APPLICATION:                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");                    AppBindData data = (AppBindData)msg.obj;                    handleBindApplication(data);                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                    break;

第四十二步 :handleBindApplication(),在ActivityThread.java中

private void handleBindApplication(AppBindData data) {        mBoundApplication = data;       .....        data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);     ....        if (data.instrumentationName != null) {        .....        } else {            mInstrumentation = new Instrumentation();        }....        // Allow disk access during application and provider setup. This could        // block processing ordered broadcasts, but later processing would        // probably end up doing the same disk access.        final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();        try {            // If the app is being launched for full backup or restore, bring it up in            // a restricted environment with the base application class.            Application app = data.info.makeApplication(data.restrictedBackupMode, null);            mInitialApplication = app;.....            // Do this after providers, since instrumentation tests generally start their            // test thread at this point, and we don't want that racing.            try {                mInstrumentation.onCreate(data.instrumentationArgs);            }            catch (Exception e) {           ....            }            try {                mInstrumentation.callApplicationOnCreate(app);            } catch (Exception e) {            .....            }        } finally {            StrictMode.setThreadPolicy(savedPolicy);        }    }

这里主要做了两件事,创建了Instrumentation对象(第五步①),创建Application对象,调用其onCreate()方法.如果有需要的话我们可以自定义Application对象继承Application类,在清单配置文件里android:name=".MyApplication">  name属性里写自己的application对象.

好了回到第三十七步 第二个函数.

第四十三步:realStartActivityLocked(),在ActivityManagerService.java中

final boolean realStartActivityLocked(ActivityRecord r,            ProcessRecord app, boolean andResume, boolean checkConfig)            throws RemoteException {       ......            app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,                    System.identityHashCode(r), r.info,                    new Configuration(mService.mConfiguration),                    r.compat, r.icicle, results, newIntents, !andResume,                    mService.isNextTransitionForward(), profileFile, profileFd,                    profileAutoStop);                     ....                    } catch (RemoteException e) {          ....        }        r.launchFailed = false;        if (updateLRUListLocked(r)) {            Slog.w(TAG, "Activity " + r                  + " being launched, but already in LRU list");        }        if (andResume) {            // As part of the process of launching, ActivityThread also performs            // a resume.            r.state = ActivityState.RESUMED;            if (DEBUG_STATES) Slog.v(TAG, "Moving to RESUMED: " + r                    + " (starting new instance)");            r.stopped = false;            mResumedActivity = r;            r.task.touchActiveTime();            if (mMainStack) {                mService.addRecentTaskLocked(r.task);            }            completeResumeLocked(r);            checkReadyForSleepLocked();            if (DEBUG_SAVED_STATE) Slog.i(TAG, "Launch completed; removing icicle of " + r.icicle);        } else {            // This activity is not starting in the resumed state... which            // should look like we asked it to pause+stop (but remain visible),            // and it has done so and reported back the current icicle and            // other state.            if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r                    + " (starting in stopped state)");            r.state = ActivityState.STOPPED;            r.stopped = true;        }        // Launch the new version setup screen if needed.  We do this -after-        // launching the initial activity (that is, home), so that it can have        // a chance to initialize itself while in the background, making the        // switch back to it faster and look better.        if (mMainStack) {            mService.startSetupActivityLocked();        }                return true;    }

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

第四十四步:scheduleLaunchActivity(),在ApplicationThreadNative.java中

 public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,            ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,            Bundle state, List pendingResults,    List pendingNewIntents, boolean notResumed, boolean isForward,    String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler)    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);        compatInfo.writeToParcel(data, 0);        data.writeBundle(state);        data.writeTypedList(pendingResults);        data.writeTypedList(pendingNewIntents);        data.writeInt(notResumed ? 1 : 0);        data.writeInt(isForward ? 1 : 0);        data.writeString(profileName);        if (profileFd != null) {            data.writeInt(1);            profileFd.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);        } else {            data.writeInt(0);        }        data.writeInt(autoStopProfiler ? 1 : 0);        mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION, data, null,                IBinder.FLAG_ONEWAY);        data.recycle();    }
case SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION:        {            data.enforceInterface(IApplicationThread.descriptor);            Intent intent = Intent.CREATOR.createFromParcel(data);            IBinder b = data.readStrongBinder();            int ident = data.readInt();            ActivityInfo info = ActivityInfo.CREATOR.createFromParcel(data);            Configuration curConfig = Configuration.CREATOR.createFromParcel(data);            CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);            Bundle state = data.readBundle();            List ri = data.createTypedArrayList(ResultInfo.CREATOR);            List pi = data.createTypedArrayList(Intent.CREATOR);            boolean notResumed = data.readInt() != 0;            boolean isForward = data.readInt() != 0;            String profileName = data.readString();            ParcelFileDescriptor profileFd = data.readInt() != 0                    ? data.readFileDescriptor() : null;            boolean autoStopProfiler = data.readInt() != 0;            scheduleLaunchActivity(intent, b, ident, info, curConfig, compatInfo, state, ri, pi,                    notResumed, isForward, profileName, profileFd, autoStopProfiler);            return true;        }

第四十五步 :scheduleLaunchActivity(),在ActivityThread.java中.在目标activity所在的进程中

  public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,                ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,                Bundle state, List pendingResults,                List pendingNewIntents, boolean notResumed, boolean isForward,                String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {            ActivityClientRecord r = new ActivityClientRecord();            r.token = token;            r.ident = ident;            r.intent = intent;            r.activityInfo = info;            r.compatInfo = compatInfo;            r.state = state;            r.pendingResults = pendingResults;            r.pendingIntents = pendingNewIntents;            r.startsNotResumed = notResumed;            r.isForward = isForward;            r.profileFile = profileName;            r.profileFd = profileFd;            r.autoStopProfiler = autoStopProfiler;            updatePendingConfiguration(curConfig);            queueOrSendMessage(H.LAUNCH_ACTIVITY, r);        }

第四十六步 :queueOrSendMessage(),在ActivityThread.java中
private void queueOrSendMessage(int what, Object obj) {        queueOrSendMessage(what, obj, 0, 0);    }

第四十七步 :queueOrSendMessage(),在ActivityThread.java中
private void queueOrSendMessage(int what, Object obj, int arg1, int arg2) {        synchronized (this) {            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;            mH.sendMessage(msg);        }    }
第四十八步 :handleMessage(),在ActivityThread.java中
 public void handleMessage(Message msg) {            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));            switch (msg.what) {                case LAUNCH_ACTIVITY: {                    ....                    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(),在ActivityThread.java中

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {        // If we are getting ready to gc after going to the background, well        // we are back active so skip it.        unscheduleGcIdler();        if (r.profileFd != null) {        .....        }        // Make sure we are running with the most recent config.        handleConfigurationChanged(null, null);        if (localLOGV) Slog.v(            TAG, "Handling launch of " + r);        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);            if (!r.activity.mFinished && r.startsNotResumed) {                // The activity manager actually wants this one to start out                // paused, because it needs to be visible but isn't in the                // foreground.  We accomplish this by going through the                // normal startup (because activities expect to go through                // onResume() the first time they run, before their window                // is displayed), and then pausing it.  However, in this case                // we do -not- need to do the full pause cycle (of freezing                // and such) because the activity manager assumes it can just                // retain the current state it has.                try {                    r.activity.mCalled = false;                    mInstrumentation.callActivityOnPause(r.activity);                    // We need to keep around the original state, in case                    // we need to be created again.  But we only do this                    // for pre-Honeycomb apps, which always save their state                    // when pausing, so we can not have them save their state                    // when restarting from a paused state.  For HC and later,                    // we want to (and can) let the state be saved as the normal                    // part of stopping the activity.                    if (r.isPreHoneycomb()) {                        r.state = oldState;                    }                    if (!r.activity.mCalled) {                        throw new SuperNotCalledException(                            "Activity " + r.intent.getComponent().toShortString() +                            " did not call through to super.onPause()");                    }                } catch (SuperNotCalledException e) {                    throw e;                } catch (Exception e) {                    if (!mInstrumentation.onException(r.activity, e)) {                        throw new RuntimeException(                                "Unable to pause activity "                                + r.intent.getComponent().toShortString()                                + ": " + e.toString(), e);                    }                }                r.paused = true;            }        } else {            // If there was an error, for any reason, tell the activity            // manager to stop us.            try {                ActivityManagerNative.getDefault()                    .finishActivity(r.token, Activity.RESULT_CANCELED, null);            } catch (RemoteException ex) {                // Ignore            }        }    }
首先看performLaunchActivity()函数.

第五十步:performLaunchActivity(),在ActivityThread.java中

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {        // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");        ActivityInfo aInfo = r.activityInfo;        if (r.packageInfo == null) {           ...        }        ComponentName component = r.intent.getComponent();        if (component == null) {            ....        }        if (r.activityInfo.targetActivity != null) {            ...        }        Activity activity = null;        try {            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();            activity = mInstrumentation.newActivity(                    cl, component.getClassName(), r.intent);//创建了activity            StrictMode.incrementExpectedActivityCount(activity.getClass());            r.intent.setExtrasClassLoader(cl);            if (r.state != null) {                r.state.setClassLoader(cl);            }        } catch (Exception e) {         ....        }        try {            Application app = r.packageInfo.makeApplication(false, mInstrumentation);//这里直接取回来,第四十二步已经创建好了            if (activity != null) {                Context appContext = createBaseContextForActivity(r, activity);                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());                Configuration config = new Configuration(mCompatConfiguration);              ..                activity.attach(appContext, this, getInstrumentation(), r.token,                        r.ident, app, r.intent, r.activityInfo, title, r.parent,                        r.embeddedID, r.lastNonConfigurationInstances, config);                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;                mInstrumentation.callActivityOnCreate(activity, r.state);//会调用到activity的onCreat()                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();//会调用到activity的onStart()                    r.stopped = false;                }                if (!r.activity.mFinished) {                    if (r.state != null) {                        mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);//可能会调用activity的onRestoreInstanceState()                    }                }                if (!r.activity.mFinished) {                    activity.mCalled = false;                    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) {       ..        }        return activity;    }

这里首先创建Activity对象,

然后调用attach()函数给它的内部变量赋值.r.parent,  r.embeddedID都为null 对应第五步⑤,第六步①.

接着会分别会调用到Activity的onCreat(),onStart(),onRestoreInstanceState()(可能会被调用)这些方法大家很熟悉吧.

好了,回到四十九步看第二个方法.

第五十一步:handleResumeActivity(),在ActivityThread.java中

 final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward,            boolean reallyResume) {        // If we are getting ready to gc after going to the background, well        // we are back active so skip it.        unscheduleGcIdler();        ActivityClientRecord r = performResumeActivity(token, clearHide);        if (r != null) {            final Activity a = r.activity;            if (localLOGV) Slog.v(                TAG, "Resume " + r + " started activity: " +                a.mStartedActivity + ", hideForNow: " + r.hideForNow                + ", finished: " + a.mFinished);            final int forwardBit = isForward ?                    WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;            // If the window hasn't yet been added to the window manager,            // and this guy didn't finish itself or start another activity,            // then go ahead and add the window.            boolean willBeVisible = !a.mStartedActivity;            if (!willBeVisible) {                try {                    willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible(                            a.getActivityToken());                } catch (RemoteException e) {                }            }            if (r.window == null && !a.mFinished && willBeVisible) {                r.window = r.activity.getWindow();                View decor = r.window.getDecorView();                decor.setVisibility(View.INVISIBLE);                ViewManager wm = a.getWindowManager();                WindowManager.LayoutParams l = r.window.getAttributes();                a.mDecor = decor;                l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;                l.softInputMode |= forwardBit;                if (a.mVisibleFromClient) {                    a.mWindowAdded = true;                    wm.addView(decor, l);//添加到wms 然后显示界面                }            // If the window has already been added, but during resume            // we started another activity, then don't yet make the            // window visible.            } else if (!willBeVisible) {                if (localLOGV) Slog.v(                    TAG, "Launch " + r + " mStartedActivity set");                r.hideForNow = true;            }     ......        return r;  }

performResumeActivity()方法最终会调用activity的onResume()方法,这时activity算是完全启动了,接下就是请求显示界面了.

好了分析到此.

最后总结一下:

用户在Launcher程序里点击应用图标时,会通知ActivityManagerService启动应用的默认Activity,ActivityManagerService发现这个应用还未启动,则会通知Zygote进程孵化出应用进程,然后在这个dalvik应用进程里执行ActivityThread的main方法。应用进程接下来通知ActivityManagerService应用进程已启动,ActivityManagerService保存应用进程的一个代理对象(applicationthread),这样ActivityManagerService可以通过这个代理对象控制应用进程,然后ActivityManagerService通知应用进程创建入口Activity的实例,并执行它的生命周期方法.














,



更多相关文章

  1. Android(安卓)AudioTrack分析
  2. Android中Fragment的应用(android官方教程完美翻译)
  3. android intent和intent action大全
  4. Android之——系统进程与用户进程分离
  5. [置顶] Android启动过程的深入研究
  6. Android(安卓)面试问题
  7. j2me与android的区别
  8. Android的View和ViewGroup深入分析
  9. 箭头函数的基础使用

随机推荐

  1. Android获取屏幕宽度与高度
  2. android 在TextView中显示EditText,通过B
  3. 【转】Android字体小结
  4. Android文本框布局实例
  5. Android-XmlPullParser解析XML
  6. Android开发个人小记
  7. 如何将library项目打包成jar文件
  8. How to decompile .dex file on Android
  9. Android Studio 4.0 新功能之 AndroidKot
  10. arcgis for android常见问题回答