美文网首页
Android的Launcher启动过程分析(1)

Android的Launcher启动过程分析(1)

作者: 快乐猿Days | 来源:发表于2019-01-16 19:11 被阅读21次

    Launcher启动前

    我们知道init进程是Android系统中用户空间的第一个进程,它创建zygote(孵化器)和属性服务等。接着在Android系统中,DVM(Dalvik虚拟机)、应用程序进程以及运行系统的关键服务的SystemServer进程都是由Zygote进程来创建的,我们也将它称为孵化器。它通过fock(复制进程)的形式来创建应用程序进程和SystemServer进程,由于Zygote进程在启动时会创建DVM,因此通过fock而创建的应用程序进程和SystemServer进程可以在内部获取一个DVM的实例拷贝。 当SystemServer启动时它会启动Binder线程池,这样就可以与其他进程进行通信;它同时也创建了SystemServiceManager用于对系统的服务进行创建、启动、和生命周期的管理;SystemServiceManager.startService(Class<T> serviceClass)方法中通过反射创建并启动服务,同时将服务返回。
    SystemServer.java中:

     private void run() {
            // Start services.
    ...........此处省略
            try {
                traceBeginAndSlog("StartServices");
                startBootstrapServices();
                startCoreServices();
                startOtherServices();
                SystemServerInitThreadPool.shutdown();
            } catch (Throwable ex) {
                Slog.e("System", "******************************************");
                Slog.e("System", "************ Failure starting system services", ex);
                throw ex;
            } finally {
                traceEnd();
            }
    ...........此处省略
    

    SystemServiceManager.java中:

    public <T extends SystemService> T startService(Class<T> serviceClass) {
            try {
                final String name = serviceClass.getName();
                Slog.i(TAG, "Starting " + name);
                Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartService " + name);
    
                // Create the service.
                if (!SystemService.class.isAssignableFrom(serviceClass)) {
                    throw new RuntimeException("Failed to create " + name
                            + ": service must extend " + SystemService.class.getName());
                }
                final T service;
                try {
                    Constructor<T> constructor = serviceClass.getConstructor(Context.class);
                    service = constructor.newInstance(mContext);
                } ...//省略部分catch
    
                startService(service);
                return service;
            } finally {
                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
            }
        }
    
    

    Launcher概述

    Android系统启动的最后一步是启动一个Home应用程序,这个应用程序用来显示系统中已经安装的应用程序,这个Home应用程序就叫做Launcher。应用程序Launcher在启动过程中会PackageManagerService返回系统中已经安装的应用程序的信息,并将这些信息封装成一个快捷图标列表显示在系统屏幕上,这样用户可以通过点击这些快捷图标来启动相应的应用程序。

    Launcher的启动流程

    我们知道SystemServer进程再启动的过程中会启动PackageManagerService,PackageManagerService启动后会将系统中的应用程序安装完成。在此之前已经启动的ActivityManagerService会将Launcher启动起来,Launcher的入口为ActivityManagerService的systemReady函数:
    com.android.server.SystemServer.java

     private void startBootstrapServices() {
                    ...............   
              // Activity manager runs the show.
            traceBeginAndSlog("StartActivityManager");
            mActivityManagerService = mSystemServiceManager.startService(
                    ActivityManagerService.Lifecycle.class).getService();
            mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
            mActivityManagerService.setInstaller(installer);
            traceEnd();
                   .....................
    }
    
     private void startOtherServices() {
                      ...................
            mActivityManagerService.systemReady(() -> {
                Slog.i(TAG, "Making services ready");
                traceBeginAndSlog("StartActivityManagerReadyPhase");
                mSystemServiceManager.startBootPhase(
                        SystemService.PHASE_ACTIVITY_MANAGER_READY)
                   ...................
    })
    

    在startOtherServices函数中,会调用ActivityManagerService的systemReady函数:
    com.android.server.am.ActivityManagerService

    public void systemReady(final Runnable goingCallback) {
    ...
    synchronized (this) {
               ...
                mStackSupervisor.resumeFocusedStackTopActivityLocked();
                mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
            }
        }
    

    systemReady函数中调用了ActivityStackSupervisor的resumeFocusedStackTopActivityLocked函数:
    com.android.server.am.ActivityStackSupervisor

    boolean resumeFocusedStackTopActivityLocked(
                ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
    
            if (!readyToResume()) {
                return false;
            }
    
            if (targetStack != null && isFocusedStack(targetStack)) {
                return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
            }
    
            final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
            if (r == null || !r.isState(RESUMED)) {
                mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
            } else if (r.isState(RESUMED)) {
                // Kick off any lingering app transitions form the MoveTaskToFront operation.
                mFocusedStack.executeAppTransition(targetOptions);
            }
    
            return false;
        }
    

    targetStack.resumeTopActivityUncheckedLocked(target, targetOptions)中的targetStack(ActivityStack)对象是用来描述Activity堆栈的,resumeTopActivityUncheckedLocked函数如下所示:
    com.android.server.am.ActivityStack

     @GuardedBy("mService")
        boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
            if (mStackSupervisor.inResumeTopActivity) {
                // Don't even start recursing.
                return false;
            }
    
            boolean result = false;
            try {
                // Protect against recursion.
                mStackSupervisor.inResumeTopActivity = true;
                result = resumeTopActivityInnerLocked(prev, options);
    
                // When resuming the top activity, it may be necessary to pause the top activity (for
                // example, returning to the lock screen. We suppress the normal pause logic in
                // {@link #resumeTopActivityUncheckedLocked}, since the top activity is resumed at the
                // end. We call the {@link ActivityStackSupervisor#checkReadyForSleepLocked} again here
                // to ensure any necessary pause logic occurs. In the case where the Activity will be
                // shown regardless of the lock screen, the call to
                // {@link ActivityStackSupervisor#checkReadyForSleepLocked} is skipped.
                final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
                if (next == null || !next.canTurnScreenOn()) {
                    checkReadyForSleep();
                }
            } finally {
                mStackSupervisor.inResumeTopActivity = false;
            }
    
            return result;
        }
    

    在该函数中如果ActivityStackSupervisor的inResumeTopActivity递归控制 Tag为true 设为false,终止递归。接着调用了resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options)函数,resumeTopActivityInnerLocked函数的代码很长,我们截取我们要分析的关键的一句:调用ActivityStackSupervisor的resumeHomeStackTask函数,代码如下所示:

    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    ....
            if (!hasRunningActivity) {
                // There are no activities left in the stack, let's look somewhere else.
                return resumeTopActivityInNextFocusableStack(prev, options, "noMoreActivities");
            }
    ...
    }
    

    接着又调用了resumeTopActivityInNextFocusableStack函数,代码如下所示:

     private boolean resumeTopActivityInNextFocusableStack(ActivityRecord prev,
                ActivityOptions options, String reason) {
            if (adjustFocusToNextFocusableStack(reason)) {
                // Try to move focus to the next visible stack with a running activity if this
                // stack is not covering the entire screen or is on a secondary display (with no home
                // stack).
                return mStackSupervisor.resumeFocusedStackTopActivityLocked(
                        mStackSupervisor.getFocusedStack(), prev, null);
            }
    
            // Let's just start up the Launcher...
            ActivityOptions.abort(options);
            if (DEBUG_STATES) Slog.d(TAG_STATES,
                    "resumeTopActivityInNextFocusableStack: " + reason + ", go home");
            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
            // Only resume home if on home display
            return isOnHomeDisplay() &&
                    mStackSupervisor.resumeHomeStackTask(prev, reason);
        }
    

    接着看继续调用了resumeHomeStackTask(prev, reason)函数:

     boolean resumeHomeStackTask(ActivityRecord prev, String reason) {
            if (!mService.mBooting && !mService.mBooted) {
                // Not ready yet!
                return false;
            }
    
            mHomeStack.moveHomeStackTaskToTop();
            ActivityRecord r = getHomeActivity();
            final String myReason = reason + " resumeHomeStackTask";
    
            // Only resume home activity if isn't finishing.
            if (r != null && !r.finishing) {
                moveFocusableActivityStackToFrontLocked(r, myReason);
                return resumeFocusedStackTopActivityLocked(mHomeStack, prev, null);
            }
            return mService.startHomeActivityLocked(mCurrentUser, myReason);
        }
    

    我们看到它最后调用了ActivityManagerService的startHomeActivityLocked(mCurrentUser, myReason)函数:

     boolean startHomeActivityLocked(int userId, String reason) {
            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
                    && mTopAction == null) { //tag1
                // We are running in factory test mode, but unable to find
                // the factory test app, so just sit around displaying the
                // error message and don't try to start anything.
                return false;
            }
            Intent intent = getHomeIntent();//tag2
            ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
            if (aInfo != null) {
                intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
                // Don't do this if the home app is currently being
                // instrumented.
                aInfo = new ActivityInfo(aInfo);
                aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
                ProcessRecord app = getProcessRecordLocked(aInfo.processName,
                        aInfo.applicationInfo.uid, true);
                if (app == null || app.instr == null) {  //tag3
                    intent.setFlags(intent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
                    final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
                    // For ANR debugging to verify if the user activity is the one that actually
                    // launched.
                    final String myReason = reason + ":" + userId + ":" + resolvedUserId;
                    mActivityStartController.startHomeActivity(intent, aInfo, myReason);//tag4
                }
            } else {
                Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
            }
    
            return true;
        }
    

    在tag1地方的mFactoryTest代表系统的运行模式,系统的运行模式分为非工厂模式、低级工厂模式、高级工厂模式。mTopAction则用来描述第一个被启动Activity组件的Action,它的值为Intent.ACTION_MAIN。所以当它为null并且是低级工程模式时什么也不启动。
    tag2地方调用了getHomeIntent函数代码如下:

    Intent getHomeIntent() {
            Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
            intent.setComponent(mTopComponent);
            intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
                intent.addCategory(Intent.CATEGORY_HOME);
            }
            return intent;
        }
    
    

    getHomeIntent函数中创建了Intent,并将mTopAction和mTopData传入。mTopAction的值为Intent.ACTION_MAIN,并且如果系统运行模式不是低级工厂模式则将intent的Category设置为Intent.CATEGORY_HOME。我们再回到ActivityManagerService的startHomeActivityLocked函数,假设系统的运行模式不是低级工厂模式,在注释3处判断符合Action为Intent.ACTION_MAIN,Category为Intent.CATEGORY_HOME的应用程序是否已经启动,如果没启动则调用注释4的方法启动该应用程序。
    这个被启动的应用程序就是Launcher,因为Launcher的Manifest文件中的intent-filter标签匹配了Action为Intent.ACTION_MAIN,Category为Intent.CATEGORY_HOME。Launcher的Manifest文件如下所示。
    /Volumes/android/WORKING_DIRECTORY/packages/apps/Launcher3/AndroidManifest.xml

    <?xml version="1.0" encoding="utf-8"?>
    <manifest
        xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.android.launcher3">
        <uses-sdk android:targetSdkVersion="23" android:minSdkVersion="21"/>
       
        ....
        <application
            android:backupAgent="com.android.launcher3.LauncherBackupAgent"
            android:fullBackupOnly="true"
            android:fullBackupContent="@xml/backupscheme"
            android:hardwareAccelerated="true"
            android:icon="@drawable/ic_launcher_home"
            android:label="@string/derived_app_name"
            android:theme="@style/AppTheme"
            android:largeHeap="@bool/config_largeHeap"
            android:restoreAnyVersion="true"
            android:supportsRtl="true" >
    <!--
            Main launcher activity. When extending only change the name, and keep all the
            attributes and intent filters the same
            -->
            <activity
                android:name="com.android.launcher3.Launcher"
                android:launchMode="singleTask"
                android:clearTaskOnLaunch="true"
                android:stateNotNeeded="true"
                android:windowSoftInputMode="adjustPan"
                android:screenOrientation="unspecified"
                android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize"
                android:resizeableActivity="true"
                android:resumeWhilePausing="true"
                android:taskAffinity=""
                android:enabled="true">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.HOME" />
                    <category android:name="android.intent.category.DEFAULT" />
                    <category android:name="android.intent.category.MONKEY"/>
                    <category android:name="android.intent.category.LAUNCHER_APP" />
                </intent-filter>
            </activity>
    ....
        </application>
    </manifest>
    
    

    这样,应用程序Launcher就会被启动起来,并执行它的onCreate函数。

    相关文章

      网友评论

          本文标题:Android的Launcher启动过程分析(1)

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