Android应用程序的启动过程源码解析—点击图标启动过程

来源:互联网 发布:js创建一个数组 编辑:程序博客网 时间:2024/05/19 05:05

转载请注明出处:http://blog.csdn.net/qianhaifeng2012/article/details/52039053


在Android系统中,有两种操作会引发Activity的启动,一种用户点击应用程序图标时,Launcher会为我们启动应用程序的主Activity;应用程序的默认Activity启动起来后,它又可以在内部通过调用startActvity接口启动新的Activity,依此类推,每一个Activity都可以在内部启动新的Activity。通过这种连锁反应,按需启动Activity,从而完成应用程序的功能。

本文主要讲点击应用图标,启动应用程序的过程。

在手机屏幕中点击应用程序图标的情景就会引发Android应用程序中的默认Activity的启动,从而把应用程序启动起来。这种启动方式的特点是会启动一个新的进程来加载相应的Activity。这里,我们以这个例子为例来说明Android应用程序的启动过程,即MainActivity的启动过程。

1、Launcher.startActivitySafely

Launcher,也就是Android系统的桌面应用程序。我们自己安装的应用的图标会在Launcher上显示,当点击应用图标时,会出发Launcher.startActivitySafely方法的执行。

源码如下:

    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(intent, tag);        } else if (tag instanceof FolderInfo) {            handleFolderClick((FolderInfo) tag);        } else if (v == mHandleView) {            if (isAllAppsVisible()) {                closeAllApps(true);            } else {                showAllApps(true);            }        }    }

    void startActivitySafely(Intent intent, Object tag) {        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);        try {            startActivity(intent);        } 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);        } catch (SecurityException e) {            Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();            Log.e(TAG, "Launcher does not have the permission to launch " + intent +                    ". Make sure to create a MAIN intent-filter for the corresponding activity " +                    "or use the exported attribute for this activity. "                    + "tag="+ tag + " intent=" + intent, e);        }    }


当点击Launcher上面应用图标的时候,就会出发onClick方法的执行,然后根据传入参数View v的v.getTag()方法得到被点击应用图标的ShortcutInfo,然后得到Intent数据。通过final Intent intent = ((ShortcutInfo) tag).intent。语句得到数据。有了一个应用的Intent就可以启动一个应用了。

接着startActivitySafely又调用Activity的startActivity方法,并且传入参数intent,添加FLAG,FLAG_ACTIVITY_NEW_TASK。然后转入Activity的startActivity方法。

这里的intent包含的信息为:action = "android.intent.action.Main",category="android.intent.category.LAUNCHER", cmp="shy.luo.activity/.MainActivity",表示它要启动的Activity为shy.luo.activity.MainActivity。Intent.FLAG_ACTIVITY_NEW_TASK表示要在一个新的Task中启动这个Activity,注意,Task是Android系统中的概念,它不同于进程Process的概念。简单地说,一个Task是一系列Activity的集合,这个集合是以堆栈的形式来组织的,遵循后进先出的原则。

稍微扩展一下:

我们知道,一个应用程序可以有多个Activity,每个Activity是同级别的。那么在启动程序时,最先启动哪个Activity呢?有些程序可能需要显示在程 序列表里,有些不需要。怎么定义呢?android.intent.action.MAIN决定应用程序最先启动的Activity ,android.intent.category.LAUNCHER决定应用程序是否显示在程序列表里。Main和LAUNCHER同时设定才有意义,如果有多个同级的Activity都有过滤器
<intent-filter>
 <action android:name="android.intent.action.MAIN" />
 <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
   则只有最前面的Activity的 <action android:name="android.intent.action.MAIN" /> 有 效,启动该程序时,执行的是该Activity。且在程序列表中有多个图标,这些Activity都在程序列表中显示,该Application有多个入 口,执行不同的Activity,但是整个程序的主入口(整个程序最先运行的那个activity)只有最先定义的那个Activity。


   如 果一个应用没有LAUNCHER则该apk仍能安装到设备上,但是在主程序图中看不到。如果给那个Activity 设定了LAUNCHER,且同时设定了Main,则这个Activity就可出现在程序图中;如果没有Main,则不知启动哪个Activity,故也不 会有图标出现。


2、Activity.startActivity

Launcher继承于Activity类,而Activity类实现了startActivity函数,因此,这里就调用了Activity.startActivity方法

    @Override    public void startActivity(Intent intent) {        this.startActivity(intent, null);    }

    @Override    public void startActivity(Intent intent, @Nullable Bundle options) {        if (options != null) {            startActivityForResult(intent, -1, options);        } else {            // Note we want to go through this call for compatibility with            // applications that may have overridden the method.            startActivityForResult(intent, -1);        }    }

可以看出Activity.startActivity方法又调用了Activity.startActivityForResult方法



3. Activity.startActivityForResult

        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) {                mStartedActivity = true;            }            cancelInputsAndStartExitTransition(options);        } else {            if (options != null) {                mParent.startActivityFromChild(this, intent, requestCode, options);            } else {                mParent.startActivityFromChild(this, intent, requestCode);            }        }    }


这里的mInstrumentation是Activity类的成员变量,它的类型是Intrumentation,定义在Instrumentation.java文件中,它用来监控应用程序和系统的交互。
         这里的mMainThread也是Activity类的成员变量,它的类型是ActivityThread,它代表的是应用程序的主线程。这里通过mMainThread.getApplicationThread获得它里面的ApplicationThread成员变量,它是一个Binder对象,ActivityManagerService会使用它来和ActivityThread来进行进程间通信,

这里我们需注意的是,这里的mMainThread代表的是Launcher应用程序运行的进程

 这里的mToken也是Activity类的成员变量,它是一个Binder对象的远程接口。


4. Instrumentation.execStartActivity


   public ActivityResult execStartActivity(            Context who, IBinder contextThread, IBinder token, Activity target,            Intent intent, int requestCode, Bundle options) {        IApplicationThread whoThread = (IApplicationThread) contextThread;        Uri referrer = target != null ? target.onProvideReferrer() : null;        if (referrer != null) {            intent.putExtra(Intent.EXTRA_REFERRER, referrer);        }        if (mActivityMonitors != null) {            synchronized (mSync) {                final int N = mActivityMonitors.size();                for (int i=0; i<N; i++) {                    final ActivityMonitor am = mActivityMonitors.get(i);                    if (am.match(who, null, intent)) {                        am.mHits++;                        if (am.isBlocking()) {                            return requestCode >= 0 ? am.getResult() : null;                        }                        break;                    }                }            }        }        try {            intent.migrateExtraStreamToClipData();            intent.prepareToLeaveProcess();            int result = ActivityManagerNative.getDefault()                .startActivity(whoThread, who.getBasePackageName(), intent,                        intent.resolveTypeIfNeeded(who.getContentResolver()),                        token, target != null ? target.mEmbeddedID : null,                        requestCode, 0, null, options);            checkStartActivityResult(result, intent);        } catch (RemoteException e) {            throw new RuntimeException("Failure from system", e);        }        return null;    }

从上面的代码可以看出,启动Activity真正的实现由ActivityManagerNative.getDefault()的.startActivity方法执行。这里的ActivityManagerNative.getDefault()我在Android中的代理模式已经详细分析过了,它返回的是一个ActivityManagerService的一个代理类ActivityManagerProxy。


5. ActivityManagerProxy.startActivity


ActivityManagerProxy是ActivityManagerNative中的一个内部类。startActivity方法源码如下。


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


这里的参数比较多,我们先整理一下。从上面的调用可以知道,这里的参数resolvedType、grantedUriPermissions和resultWho均为null;参数caller为ApplicationThread类型的Binder实体;参数resultTo为一个Binder实体的远程接口,我们先不关注它;参数grantedMode为0,我们也先不关注它;参数requestCode为-1;参数onlyIfNeeded和debug均空false。



由于ActivityManagerProxy是一个代理类,上面是通过IPC的Binder联系到ActivityManagerService,最后会调用

ActivityManagerService的startActivity方法。



6. ActivityManagerService.startActivity

startActivity又调用了startActivityAsUser方法。

源码如下

    @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) {        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.        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,                profilerInfo, null, null, options, false, userId, null, null);    }


这里的mStackSupervisor的类型是ActivityStackSupervisor。


7.ActivityStackSupervisor.startActivityMayWait

这个方法代码比较长,这里摘抄主要部分代码

    final int startActivityMayWait(IApplicationThread caller, int callingUid,            String callingPackage, Intent intent, String resolvedType,            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,            IBinder resultTo, String resultWho, int requestCode, int startFlags,            ProfilerInfo profilerInfo, WaitResult outResult, Configuration config,            Bundle options, boolean ignoreTargetSecurity, int userId,            IActivityContainer iContainer, TaskRecord inTask) {       .................................        ActivityInfo aInfo =                resolveActivity(intent, resolvedType, startFlags, profilerInfo, userId);        ....................................................            int res = startActivityLocked(caller, intent, resolvedType, aInfo,                    voiceSession, voiceInteractor, resultTo, resultWho,                    requestCode, callingPid, callingUid, callingPackage,                    realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity,                    componentSpecified, null, container, inTask);...........................................            return res;            }

其中的resolveActivity方法主要是获得对参数intent的内容进行解析,得到MainActivity的相关信息,保存在aInfo变量中:resolveActivity方法如下

省略无关代码。

   ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,            ProfilerInfo profilerInfo, int userId) {                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;        }       ......................................        return aInfo;    }

解析之后,得到的aInfo.applicationInfo.packageName的值为应用的包名,aInfo.name的值为MainActivity的完整名称,被定为<action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" />的Activity,这是在这个实例的配置文件AndroidManifest.xml里面配置的。


然后又调用了startActivityLocked方法



8. ActivityStackSupervisor.startActivityLocked


这个方法200多行,截取主要部分代码

    final int startActivityLocked(IApplicationThread caller,            Intent intent, String resolvedType, ActivityInfo aInfo,            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,            IBinder resultTo, String resultWho, int requestCode,            int callingPid, int callingUid, String callingPackage,            int realCallingPid, int realCallingUid, int startFlags, Bundle options,            boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,            ActivityContainer container, TaskRecord inTask) {        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 {               .........................            }        }       ...........................................        ActivityRecord sourceRecord = null;        ActivityRecord resultRecord = null;        if (resultTo != null) {            sourceRecord = isInAnyStackLocked(resultTo);            if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,                    "Will send result to " + resultTo + " " + sourceRecord);            if (sourceRecord != null) {                if (requestCode >= 0 && !sourceRecord.finishing) {                    resultRecord = sourceRecord;                }            }        }        final int launchFlags = intent.getFlags();        if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {            // Transfer the result target from the source activity to the new            // one being started, including any failures.            if (requestCode >= 0) {                ActivityOptions.abort(options);                return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;            ..................................}        }        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, callerApp, callingUid, callingPackage,                intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,                requestCode, componentSpecified, voiceSession != null, this, container, options);        ....................................<pre name="code" class="java">err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,                startFlags, true, options, inTask);

return err; }

从传进来的参数caller得到调用者的进程信息,并保存在callerApp变量中,这里就是Launcher应用程序的进程信息了。 前面说过,参数resultTo是Launcher这个Activity里面的一个Binder对象,通过它可以获得Launcher这个Activity的相关信息,保存在sourceRecord变量中。

再接下来,创建即将要启动的Activity的相关信息,并保存在r变量中:

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

然后调用 ActivityStackSupervisor.startActivityUncheckedLocked方法。


9. ActivityStackSupervisor.startActivityUncheckedLocked

这个方法主要用于


1、创建Acitivity栈,根据Activity的启动模式,由于是点击图标进来的,一开始也设置了标志位Intent.FLAG_ACTIVITY_NEW_TASK,所以会新创建一个Activity栈。如果之前已经有栈,且不是singleinstance,就不会再创建新的栈,会将待启动的Activity添加到原来的栈中。



这个方法又会调用ActivityStack.resumeTopActivitiesLocked


10.ActivityStack.resumeTopActivitiesLocked


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

从上面的代码可以看出resumeTopActivitiesLocked方法又调用了resumeTopActivityInnerLocked方法,接着又调用了ActivityStackSupervisor.startSpecificActivityLocked方法。


11.ActivityStackSupervisor.resumeTopActivityInnerLocked


    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {        .................................        if (mResumedActivity != null) {            if (DEBUG_STATES) Slog.d(TAG_STATES,                    "resumeTopActivityLocked: Pausing " + mResumedActivity);            pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);        }         ...............................            mStackSupervisor.startSpecificActivityLocked(next, true, true);       ........................        return true;    }

这里摘抄了resumeTopActivityInnerLocked的两个部分

1)调用startPausingLocked方法,最终会通过ActivityManagerService通过Binder进程间通信机制通知Launcher进入Paused状态;如果是通过其他Activity启动的。会将其他Activity进入Paused状态。由于这里是Launcher发起的startActivity,所以Launcher进入Paused状态。


2)调用了ActivityStackSupervisor.startSpecificActivityLocked方法。




12.ActivityStackSupervisor.startSpecificActivityLocked


    void startSpecificActivityLocked(ActivityRecord r,            boolean andResume, boolean checkConfig) {        // Is this activity's application already running?        ProcessRecord app = mService.getProcessRecordLocked(r.processName,                r.info.applicationInfo.uid, true);        r.task.stack.setLaunchTime(r);        if (app != null && app.thread != null) {            try {                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0                        || !"android".equals(r.info.packageName)) {                    // Don't add this if it is a platform component that is marked                    // to run in multiple processes, because this is actually                    // part of the framework so doesn't make sense to track as a                    // separate apk in the process.                    app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,                            mService.mProcessStats);                }                realStartActivityLocked(r, app, andResume, checkConfig);                return;            } catch (RemoteException e) {                Slog.w(TAG, "Exception when starting activity "                        + r.intent.getComponent().flattenToShortString(), e);            }            // If a dead object exception was thrown -- fall through to            // restart the application.        }        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,                "activity", r.intent.getComponent(), false, false, true);    }



在上述方法中有一句代码:

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


注意,这里由于是第一次启动应用程序的Activity,取回来的app为null。在Activity应用程序中的AndroidManifest.xml配置文件中,我们没有指定Application标签的process属性,系统就会默认使用package的名称。每一个应用程序都有自己的uid,因此,这里uid + process的组合就可以为每一个应用程序创建一个ProcessRecord。

所以下面if (app != null && app.thread != null)条件不成立,那么条件里面realStartActivityLocked 方法就不会执行,而是执行ActivityManagerService.startProcessLocked函数进行下一步操作。



13. ActivityManagerService.startProcessLocked

源码大致如下

    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {               .............................            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);           ...................        String hostingNameStr = hostingName != null                ? hostingName.flattenToShortString() : null;        if (app == null) {            checkTime(startTime, "startProcess: creating new process record");    //  创建一个新的ProcessRecord            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);            if (app == null) {                Slog.w(TAG, "Failed making new process record for "                        + processName + "/" + info.uid + " isolated=" + isolated);                return null;            }            app.crashHandler = crashHandler;            checkTime(startTime, "startProcess: done creating new process record");        } else {            ............................        }       ...............................        startProcessLocked(                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);        ........        return (app.pid != 0) ? app : null;    }


首先调用getProcessRecordLocked,但是返回的app为null,所以下面这一句就会执行。

app = newProcessRecordLocked(info, processName, isolated, isolatedUid);

newProcessRecordLocked方法会调用addProcessNameLocked方法,addProcessNameLocked方法中会执行

 mProcessNames.put(proc.processName, proc.uid, proc);


这时候mProcessNames这个全局变量就有数据了,再调用getProcessRecordLocked,返回的就不是null了。


接着,ActivityManagerService.startProcessLocked方法会执行另一个无返回值的startProcessLocked方法。


大致代码如下

    private final void startProcessLocked(ProcessRecord app, String hostingType,            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {        .............................                try {                    checkTime(startTime, "startProcess: getting gids from package manager");                    final IPackageManager pm = AppGlobals.getPackageManager();                    permGids = pm.getPackageGids(app.info.packageName, app.userId);                    MountServiceInternal mountServiceInternal = LocalServices.getService(                            MountServiceInternal.class);                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,                            app.info.packageName);                } catch (RemoteException e) {                    throw e.rethrowAsRuntimeException();                }.....................................<span style="white-space:pre"></span>entryPoint = "android.app.ActivityThread"            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实例来对应的原因。


    public static final ProcessStartResult start(final String processClass,                                  final String niceName,                                  int uid, int gid, int[] gids,                                  int debugFlags, int mountExternal,                                  int targetSdkVersion,                                  String seInfo,                                  String abi,                                  String instructionSet,                                  String appDataDir,                                  String[] zygoteArgs) {        try {            return startViaZygote(processClass, niceName, uid, gid, gids,                    debugFlags, mountExternal, targetSdkVersion, seInfo,                    abi, instructionSet, appDataDir, zygoteArgs);        } catch (ZygoteStartFailedEx ex) {            Log.e(LOG_TAG,                    "Starting VM process through Zygote failed");            throw new RuntimeException(                    "Starting VM process through Zygote failed", ex);        }    }


start方法又调用了startViaZygote方法,该方法的注释为

Starts a new process via the zygote mechanism.会通过zygote机制开启一个新的进程。由于我们导入的类名是android.app.ActivityThread,开启一个ActivityThread进程,这也是为什么一个应用程序只有一个ActivityThread,然后会执行他的main方法。


14.ActivityThread.main


这个方法就比较熟悉了,创建ActivityThread。构建消息循环系统。


    public static void main(String[] args) {        .........................        Looper.prepareMainLooper();        ActivityThread thread = new ActivityThread();        thread.attach(false);        ......................                Looper.loop();            }

其中调用了ActivityThread的attach方法。源码大致如下

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

然后会执行mgr.attachApplication方法,mgr = ActivityManagerNative.getDefault(),通过前面分析它是ActivityManagerService的代理对象ActivityManagerProxy对象。所以最终会转向ActivityManagerService的attachApplication方法。


其中mAppThread是ApplicationThread,是一个Binder对象,用于ActivityManagerService与ActivityThread通信。


15. ActivityManagerService.attachApplication

    @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方法。


16. ActivityManagerService.attachApplicationLocked

    private final boolean attachApplicationLocked(IApplicationThread thread,            int pid) {                ProcessRecord app;        if (pid != MY_PID && pid >= 0) {            synchronized (mPidsSelfLocked) {                app = mPidsSelfLocked.get(pid);            }        } else {            app = null;        }        .................................                final String processName = app.processName;        try {            AppDeathRecipient adr = new AppDeathRecipient(                    app, pid, thread);            thread.asBinder().linkToDeath(adr, 0);            app.deathRecipient = adr;        } catch (RemoteException e) {            app.resetPackageList(mProcessStats);            startProcessLocked(app, "link fail", processName);            return false;        }        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);        app.makeActive(thread, mProcessStats);        app.curAdj = app.setAdj = -100;        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;        app.forcingToForeground = null;        updateProcessForegroundLocked(app, false, false);        app.hasShownUi = false;        app.debugging = false;        app.cached = false;        app.killedByAm = false;        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);                    ..............        boolean badApp = false;        boolean didSomething = false;        // See if the top visible activity is waiting to run in this process...        if (normalMode) {            try {                if (mStackSupervisor.attachApplicationLocked(app)) {                    didSomething = true;                }            } catch (Exception e) {                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);                badApp = true;            }        }        ..............................        return true;    }

在前面的Step 13中,已经创建了一个ProcessRecord,这里首先通过pid将它取回来,放在app变量中,然后对app的其它成员进行初始化,然后另外一个attachApplicationLocked方法。

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

调用mMainStack.realStartActivityLocked执行真正的Activity启动操作。这里要启动的Activity通过调用mMainStack.topRunningActivityLocked(null)从堆栈顶端取回来,这时候在堆栈顶端的Activity就是MainActivity了。



17.ActivityManagerService.realStartActivityLocked


该方法中有下面一句:

    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),                    new Configuration(stack.mOverrideConfig), r.compat, r.launchedFromPackage,                    task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,                    newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);            ..........................        return true;    }



app.thread是是ApplicationThreadProxy对象,是一个代理对象,代理就是ApplicationThread,情况完全类似于ActivityManagerProxy代理类。所以逻辑转向了ApplicationThread的scheduleLaunchActivity方法。


18.ApplicationThread.scheduleLaunchActivity


<pre name="code" class="java">        @Override        public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,                ActivityInfo info, Configuration curConfig, Configuration overrideConfig,                CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,                int procState, Bundle state, PersistableBundle persistentState,                List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,                boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {            updateProcessState(procState, false);            ActivityClientRecord r = new ActivityClientRecord();            r.token = token;            r.ident = ident;            r.intent = intent;            r.referrer = referrer;            r.voiceInteractor = voiceInteractor;            r.activityInfo = info;            r.compatInfo = compatInfo;            r.state = state;            r.persistentState = persistentState;            r.pendingResults = pendingResults;            r.pendingIntents = pendingNewIntents;            r.startsNotResumed = notResumed;            r.isForward = isForward;            r.profilerInfo = profilerInfo;            r.overrideConfig = overrideConfig;            updatePendingConfiguration(curConfig);            sendMessage(H.LAUNCH_ACTIVITY, r);        }


 函数首先创建一个ActivityClientRecord实例,并且初始化它的成员变量,然后发送一个启动Activity的消息交给Handler处理,这个Handler有着一个很简洁的名字:H,然后看一下H对消息的处理,H定义ActivityThrad类中。

19. H.handleMessage

        public void handleMessage(Message msg) {            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));            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;...................................}

可以看出这个消息的处理交给了ActivityThread的handleLaunchActivity方法来处理。



20. ActivityThread.handleLaunchActivity


 private final 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);                ......          } else {              ......          }      }  


从上面的源码可以看出,performLaunchActivity最终完成了Activity对象的创建和启动过程,并且Activity通过handleResumeActivity方法来调用被启动Activity的onResume这一生命周期方法。而onCreate这个这个生命周期方法在performLaunchActivity方法中被回调。


21. ActivityThread.performLaunchActivity

这个方法主要完成了如下几件事

1)从ActivityClientRecord中获取待启动的Activity的组件信息。

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


2)、通过Instrumenttation的newActivity方法使用类加载器创建Activity对象。

        Activity activity = null;        try {            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();            activity = mInstrumentation.newActivity(                    cl, component.getClassName(), r.intent);            StrictMode.incrementExpectedActivityCount(activity.getClass());            r.intent.setExtrasClassLoader(cl);            r.intent.prepareToEnterProcess();            if (r.state != null) {                r.state.setClassLoader(cl);            }        } catch (Exception e) {            if (!mInstrumentation.onException(activity, e)) {                throw new RuntimeException(                    "Unable to instantiate activity " + component                    + ": " + e.toString(), e);            }        }


3)、通过LoadeApk的makeApplication方法来尝试创建Application对象


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

makeApplication方法代码如下

    public Application makeApplication(boolean forceDefaultAppClass,            Instrumentation instrumentation) {        if (mApplication != null) {            return mApplication;        }        Application app = null;        String appClass = mApplicationInfo.className;        if (forceDefaultAppClass || (appClass == null)) {            appClass = "android.app.Application";        }        try {            java.lang.ClassLoader cl = getClassLoader();            if (!mPackageName.equals("android")) {                initializeJavaContextClassLoader();            }            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);            app = mActivityThread.mInstrumentation.newApplication(                    cl, appClass, appContext);            appContext.setOuterContext(app);        } catch (Exception e) {            if (!mActivityThread.mInstrumentation.onException(app, e)) {                throw new RuntimeException(                    "Unable to instantiate application " + appClass                    + ": " + e.toString(), e);            }        }        mActivityThread.mAllApplications.add(app);        mApplication = app;        if (instrumentation != null) {            try {                instrumentation.callApplicationOnCreate(app);            } catch (Exception e) {                if (!instrumentation.onException(app, e)) {                    throw new RuntimeException(                        "Unable to create application " + app.getClass().getName()                        + ": " + e.toString(), e);                }            }        }        // Rewrite the R 'constants' for all library apks.        SparseArray<String> packageIdentifiers = getAssets(mActivityThread)                .getAssignedPackageIdentifiers();        final int N = packageIdentifiers.size();        for (int i = 0; i < N; i++) {            final int id = packageIdentifiers.keyAt(i);            if (id == 0x01 || id == 0x7f) {                continue;            }            rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id);        }        return app;    }


从makeApplication方法可以看出,通过mActivityThread.mInstrumentation.newApplication创建Application对象,然后通过callApplicationOnCreate方法间接回调onCreate方法。



4)、创建ContextImpl对象并通过Activity的attach方法来完成一些重要数据的初始化


Context appContext = createBaseContextForActivity(r, activity);                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());                Configuration config = new Configuration(mCompatConfiguration);                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "                        + r.activityInfo.name + " with config " + config);                activity.attach(appContext, this, getInstrumentation(), r.token,                        r.ident, app, r.intent, r.activityInfo, title, r.parent,                        r.embeddedID, r.lastNonConfigurationInstances, config,                        r.referrer, r.voiceInteractor);


ContextImpl是一个很重要的数据结构,它是Context的具体实现,Context中的大部分逻辑都是由ContextImpl来完成的。ContextImpl是通过Activity的attach方法来和Activity建立链接的,处理之外,在attach方法中Activity还会完成Window的创建并建立自己和Window的关联,这样当Window接受到外部输入事件后就可以将时间传递给Activity。



5)、调用Activity的onCreate

mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);

最后回调Activity的onCreate方法。这也意味着应用已经启动起来了。
























4 0