1、首先需要介绍init.rc脚本文件
该文件作为Android中LInux的第一个用户级进程init解析的,主要作用为文件系统初始化、设置环境变量、设置线程参数、装载等等。
开机后init.rc会首先装载class core以及class main的核心类(ServiceManager、SurfaceFlinger、Zygote、mediaServer)
2、开机动画的启动流程
(1)、在init.rc中有定义了bootanimation的进程服务,但是默认是disabled的

service bootanim /system/bin/bootanimation
    class core
    user graphics
    group graphics audio
    disabled
    oneshot

(2)、当init进程将SurfaceFlinger服务带起后,该服务会改变ctl.start系统变量,将其置为“bootanim”,以此来通知init进程启动应用程序bootanimation,从而开始启动开机动画

void SurfaceFlinger::init() {
...
...
...
startBootAnim();
}

void SurfaceFlinger::startBootAnim() {
    // start boot animation
    property_set("service.bootanim.exit", "0");
    property_set("ctl.start", "bootanim");
}

ps:SurfaceFlinger.cpp文件在\frameworks\native\services\surfaceflinger中,是一个.cpp文件
(3)、当系统进程将系统中的关键服务启动起来后,就会将程序启动器(Launcher)启动起来,进而通知停止显示动画
(4)、ActivityManagerService服务就会通知SurfaceFlingers服务来修改系统属性ctl.stop的值,从而通知init进程停止动画
3、加载Launcher的过程分析
(1)、开机启动后init进程会调用Zygote进程,Zygote进程会调用SystemServer进程从而调用其它的各种服务进程
(2)、在SystemServer中会启动ActivityManagerService并调用它的SystemReady()方法
(3)、在SystemReady()方法中会调用startHomeActivityLocked(mCurrentUserId, “systemReady”);方法
(4)、startActivityLocked()函数会调用getHomeIntent方法创建一个Intent,并给这个Intent设置CATEGORY_HOME类型

boolean startHomeActivityLocked(int userId, String reason) {
        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
                && mTopAction == null) {
            // 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();
        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.instrumentationClass == null) {
                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
                mStackSupervisor.startHomeActivity(intent, aInfo, reason);
            }
        }

        return true;
    }

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

(5)、将intent当做参数并调用resolveActivityInfo函数,这个函数主要用来调用PackageManagerService查询Category类型为home的activity,并返回一个activityinfo对象

private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
        ActivityInfo ai = null;
        //ComponentName用来启动其它应用程序得到Activity或者Service
        ComponentName comp = intent.getComponent();
        try {
            if (comp != null) {
                // Factory test.
                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
            } else {
                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
                        intent,
                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
                        flags, userId);

                if (info != null) {
                    ai = info.activityInfo;
                }
            }
        } catch (RemoteException e) {
            // ignore
        }

        return ai;
    }

(6)、在resolveactivityinfo函数中会调用resolveIntent()函数,在这个函数中主要做了两件事,第一,检查权限,第二,查询符合要求的activities

@Override
    public ResolveInfo resolveIntent(Intent intent, String resolvedType,
            int flags, int userId) {
        if (!sUserManager.exists(userId)) return null;
        //检查权限
        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "resolve intent");
        //查询符合要求的activities,ActivityInfo是ResolveInfo的一个变量,这里返回的是符合条件的装有ResolveInfo的集合
        List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
        return chooseBestActivity(intent, resolvedType, flags, query, userId);
    }

(7)、queryIntentActivities方法用来查询所有符合条件的activities,并查询结果作为参数传入到chooseBestActivity()中进行比较

@Override
    public List<ResolveInfo> queryIntentActivities(Intent intent,
            String resolvedType, int flags, int userId) {
        if (!sUserManager.exists(userId)) return Collections.emptyList();
        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "query intent activities");
        ComponentName comp = intent.getComponent();
        if (comp == null) {
            if (intent.getSelector() != null) {
                intent = intent.getSelector();
                comp = intent.getComponent();
            }
        }
        //判断Intent指定的模块不为空,则返回list,满足条件的只有一个
        if (comp != null) {
            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
            final ActivityInfo ai = getActivityInfo(comp, flags, userId);
            if (ai != null) {
                final ResolveInfo ri = new ResolveInfo();
                ri.activityInfo = ai;
                list.add(ri);
            }
            return list;
        }

        // reader
        synchronized (mPackages) {
            final String pkgName = intent.getPackage();
            //如果没有指定报名,在系统所有包中查找
            if (pkgName == null) {
                List<CrossProfileIntentFilter> matchingFilters =
                        getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
                // Check for results that need to skip the current profile.
                ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
                        resolvedType, flags, userId);
                if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
                    List<ResolveInfo> result = new ArrayList<ResolveInfo>(1);
                    result.add(xpResolveInfo);
                    return filterIfNotPrimaryUser(result, userId);
                }

                // Check for results in the current profile.
                List<ResolveInfo> result = mActivities.queryIntent(
                        intent, resolvedType, flags, userId);

                // Check for cross profile results.
                xpResolveInfo = queryCrossProfileIntents(
                        matchingFilters, intent, resolvedType, flags, userId);
                if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
                    result.add(xpResolveInfo);
                    Collections.sort(result, mResolvePrioritySorter);
                }
                result = filterIfNotPrimaryUser(result, userId);
                if (hasWebURI(intent)) {
                    CrossProfileDomainInfo xpDomainInfo = null;
                    final UserInfo parent = getProfileParent(userId);
                    if (parent != null) {
                        xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
                                flags, userId, parent.id);
                    }
                    if (xpDomainInfo != null) {
                        if (xpResolveInfo != null) {
                            // If we didn't remove it, the cross-profile ResolveInfo would be twice
                            // in the result.
                            result.remove(xpResolveInfo);
                        }
                        if (result.size() == 0) {
                            result.add(xpDomainInfo.resolveInfo);
                            return result;
                        }
                    } else if (result.size() <= 1) {
                        return result;
                    }
                    result = filterCandidatesWithDomainPreferredActivitiesLPr(intent, flags, result,
                            xpDomainInfo, userId);
                    Collections.sort(result, mResolvePrioritySorter);
                }
                return result;
            }
            final PackageParser.Package pkg = mPackages.get(pkgName);
             //如果Intent指定的包名不为空,则查找安装包中指定的包
            if (pkg != null) {
                return filterIfNotPrimaryUser(
                        mActivities.queryIntentForPackage(
                                intent, resolvedType, flags, pkg.activities, userId),
                        userId);
            }
            return new ArrayList<ResolveInfo>();
        }
    }

(8)、调用chooseBestActivity()方法根据查询结果,选择一个最适合的activity,并返回ResolveInfo对象

/**
    *选择并返回返回最合适的ResolveInfo
    */
    private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
            int flags, List<ResolveInfo> query, int userId) {
        if (query != null) {
            final int N = query.size();
            if (N == 1) {
                return query.get(0);
            } else if (N > 1) {
                //如果合适的Activity大于1,并且想选择我们自己的应用程序作为默认启动Launcher
                //添加代码返回返回我们需要启动的应用信息
                //for(int i = 0;i < N;i ++){
                //  ResolveInfo ri = query.get(i);
                //  if(ri.activityinfo.packageName.equals("包名"){
                //      return ri;
                //  }
                //}
                final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
                // If there is more than one activity with the same priority,
                // then let the user decide between them.
                //如果符合条件的activity大于1,则只选出前两个,进行比较进而选出优先级最高的
                ResolveInfo r0 = query.get(0);
                ResolveInfo r1 = query.get(1);
                if (DEBUG_INTENT_MATCHING || debug) {
                    Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
                            + r1.activityInfo.name + "=" + r1.priority);
                }
                // If the first activity has a higher priority, or a different
                // default, then it is always desireable to pick it.
                if (r0.priority != r1.priority
                        || r0.preferredOrder != r1.preferredOrder
                        || r0.isDefault != r1.isDefault) {
                    return query.get(0);
                }
                // If we have saved a preference for a preferred activity for
                // this Intent, use that.
                ResolveInfo ri = findPreferredActivity(intent, resolvedType,
                        flags, query, r0.priority, true, false, debug, userId);
                if (ri != null) {
                    return ri;
                }
                ri = new ResolveInfo(mResolveInfo);
                ri.activityInfo = new ActivityInfo(ri.activityInfo);
                ri.activityInfo.applicationInfo = new ApplicationInfo(
                        ri.activityInfo.applicationInfo);
                if (userId != 0) {
                    ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
                            UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
                }
                // Make sure that the resolver is displayable in car mode
                if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
                ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
                return ri;
            }
        }
        return null;
    }