Android Framework:Launcher启动

Android Framework:Launcher启动

Android系统的启动流程

① 启动电源:当我们长按手机的开机按钮时引导芯片代码从预定义的得放开始执行,加载引导程序BootLoader到RAM,然后执行。

② 引导程序BootLoader:BootLoader是在Android操作系统开始运行前的一个小程序,他的作用是负责拉起整个系统。

③ Linux内核启动:当内核启动时,设置缓存、被保存储器、计划列表、加载驱动。当内核完成系统设置时,它首先在系统文件中寻找init.rc文件,并启动。

④ init进程启动:初始化和启动属性服务,并且启动Zygote进程。

⑤ Zygote进程启动:创建java虚拟机并为java虚拟机注册jni方法,创建服务器Socket,启动SystemServer。

⑥ SystemServer进程启动:启动Binder线程池和SystemServiceManager,并且启动各种系统服务。

⑦ Launcher启动:被SystemServer启动的ActivityManagerService会启动Launcher,Launcher启动后会将已经安装的App的快捷图标显示在界面上。

启动了Launcher

/frameworks/base/services/java/com/android/server/SystemServer.java,如果了解了SystemServer.java这个类的话,就应该知道它的主要工作就是启动一系列的重要Service,找到startOtherServices方法,拉到最后,可以找到如下代码:

mActivityManagerService.systemReady(() -> {
        Slog.i(TAG, "Making services ready");
        traceBeginAndSlog("StartActivityManagerReadyPhase");
        mSystemServiceManager.startBootPhase(
                SystemService.PHASE_ACTIVITY_MANAGER_READY);
        traceEnd();
        traceBeginAndSlog("StartObservingNativeCrashes");
        try {
            mActivityManagerService.startObservingNativeCrashes();
        } catch (Throwable e) {
            reportWtf("observing native crashes", e);
        }
        traceEnd();
    ·····
    }

可以看到,在这里SystemServer调用了ActivityManagerServicesystemReady方法,进入此方法,其它的先不管,找到这段代码:

public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) {
    synchronized(this) {
        if (mSystemReady) {
            // If we're done calling all the receivers, run the next "boot phase" passed in
            // by the SystemServer
            if (goingCallback != null) {
                goingCallback.run();
            }
            return;
        }
        mStackSupervisor.resumeFocusedStackTopActivityLocked();
        mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
    }

最终会走到mStackSupervisor的resumeFocusedStackTopActivity()中,其中mStackSupervisor的类型是ActivityStackSupervisor,他是Activity栈的管理者。

boolean resumeFocusedStackTopActivityLocked() {
    return resumeFocusedStackTopActivityLocked(null, null, null);
}

接下来ActivityStackSupervisor会调用自身的resumeFocusedStackTopActivityLocked()方法。

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

最终回到用到变量mFocusedStack的resumeTopActivtyUncheckedlocked()方法。mFocusedStack是ActivityStack类型,它是描述一个Acitivty栈的类。

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);
    } finally {
        mStackSupervisor.inResumeTopActivity = false;
    }
    // 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.
    mStackSupervisor.checkReadyForSleepLocked();

    return result;
}

之后会调用ActivityStack的resumeTopActivityInnerLocked()方法并且该方法会返回一个布尔类型的调用结果。

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    if (!mService.mBooting && !mService.mBooted) {
        // Not ready yet!
        return false;
    }
    if (prevTask != null && prevTask.getStack() == this &&
            prevTask.isOverHomeStack() && prev.finishing && prev.frontOfTask) {
        if (DEBUG_STACK)  mStackSupervisor.validateTopActivitiesLocked();
        if (prevTask == nextTask) {
            prevTask.setFrontOfTask();
        } else if (prevTask != topTask()) {
            // This task is going away but it was supposed to return to the home stack.
            // Now the task above it has to return to the home task instead.
            final int taskNdx = mTaskHistory.indexOf(prevTask) + 1;
            mTaskHistory.get(taskNdx).setTaskToReturnTo(HOME_ACTIVITY_TYPE);
        } else if (!isOnHomeDisplay()) {
            return false;
        } else if (!isHomeStack()){
            if (DEBUG_STATES) Slog.d(TAG_STATES,
                    "resumeTopActivityLocked: Launching home next");
            return isOnHomeDisplay() &&
                    mStackSupervisor.resumeHomeStackTask(prev, "prevFinished"); //重点
        }
    }
}

之后又回到ActivtyStackSupervisor的resumeHomeStackTask()方法。

boolean resumeHomeStackTask(ActivityRecord prev, String reason) {
    if (!mService.mBooting && !mService.mBooted) {
        // Not ready yet!
        return false;
    }

    if (prev != null) {
        prev.getTask().setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
    }

    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);//重要
}

最后调用了mService.startHomeActivityLocked()方法。这里的mService的类型就是ActivityManagerService。

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 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.instr == null) {
            intent.setFlags(intent.getFlags() | Intent.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;
            mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
        }
    } else {
        Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
    }

    return true;
}

这个方法它会获取Activity所需的Intent和判断它的工厂模式是什么类型,最后它会找需要启动的Activity是否已经存在进程。最终它会调用ActivityStarter的startHomeActivityLocked()方法。

最后

如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。

如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
img
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。

欢迎大家一键三连支持,若需要文中资料,直接扫描文末CSDN官方认证微信卡片免费领取↓↓↓(文末还有ChatGPT机器人小福利哦,大家千万不要错过)

PS:群里还设有ChatGPT机器人,可以解答大家在工作上或者是技术上的问题
图片

  • 18
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android Framework 中查看启动服务耗时,可以通过 adb shell dumpsys activity services 命令来获取。这个命令会输出所有正在运行的服务的信息,包括它们的启动时间和耗时。 例如,假设我们要查看系统中当前正在运行的所有服务的启动耗时,可以在终端中输入以下命令: ``` adb shell dumpsys activity services ``` 输出结果中,每个服务的信息都会以如下形式显示: ``` SERVICE com.example.MyService * ServiceRecord{123456 u0 com.example/.MyService} intent={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.example/.MyService} packageName=com.example processName=com.example baseDir=/data/app/com.example-1/base.apk dataDir=/data/data/com.example app=ProcessRecord{7890 u0 com.example:myprocess/xyz} createTime=-2m28s824ms startingBgTimeout=-- lastActivity=-2m28s824ms restartTime=-2m28s824ms createdFromFg=true startRequested=true stopIfKilled=true callStart=true lastStartId=0 bindings.size=0 executingStart=-1 startId=-1 delayedStop=false stopWithTask=false lastStartForeground=false noisy=false fgg=false explicitIdle=false comp=null connection=null delayed=true delayedStop=false stopWithTask=false lastStartId=-1 destroyTime=-1 crashCount=0 restartDelay=0 restartCount=0 nextRestartTime=-1 proc=start executeNesting=1 callingIdentity=System whitelistManager=null mBoundApplication=AppBindData{...} mServiceInfo=ServiceInfo{...} mPackageName=com.example grantedUriPermissions=0 pendingStarts.size=0 lastPrincipalResuming=null retainInstance=false mStartCompatibility=0 mDispatchedStarts=[StartInfo{...}] mDelayedStop=-- mDestroyed=false mStopIfKilled=false mStopWithTask=false mStartRequested=true mDelayed=true mLastStartId=-1 mExecuteNesting=1 mAllowCancel=true mResultTo=null mService=null mHasAutoCreateConnections=false mCreateBytes=-1 mRestored=false mDestroyedByApp=false mIsForeground=false mForegroundId=0 mForegroundNoti=null mCrashCount=0 mRestartCount=0 ``` 其中,createTime 表示服务创建时间,lastActivity 表示最后一次活动时间,restartTime 表示服务重新启动时间,executeNesting 表示执行嵌套深度(如果超过 1,则表示服务正在执行其他操作,如绑定等),mCreateBytes 表示创建服务时使用的内存大小,mCrashCount 表示服务崩溃次数,mRestartCount 表示服务重启次数等。 注意,dumpsys activity services 命令会输出大量信息,如果要查找特定服务的启动时间,可以使用 grep 命令进行过滤。例如,要查看 com.example.MyService 的启动时间,可以使用以下命令: ``` adb shell dumpsys activity services | grep com.example.MyService ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值