Android Framework实战视频--SystemServer启动FallbackHome篇

Android系统开机动画结束进入launcher前黑屏优化 最近在做一个项目,发现系统开机在开机动画结束后会有6S的黑屏才进入launcher界面,严重影响使用体验。 阅读详情
AI摘要

本文详细剖析了Android 8.1系统启动时FallbackHome的启动流程,从Intent触发到ActivityManagerService,经过PackageManagerService,最终通过启动进程和Activity。重点揭示了FallbackHome如何在系统解锁前作为过渡界面,以及启动过程中的关键步骤和判断逻辑。

课程答疑和新课信息:QQ交流群:422901085进行课程讨论
FrameWork入门课视频链接:https://edu.youkuaiyun.com/course/detail/30298
FrameWork实战课1视频链接:https://edu.youkuaiyun.com/course/detail/30275
专题博客系列:
Android 8.1 zygote 启动过程源码
Android Framework实战视频–Zygote的fork进程篇
Android Framework实战视频–SystemServer启动篇
Android Framework实战视频–SystemServer启动FallbackHome篇
Android Framework实战视频–FallbackHome进程启动及Activity启动篇
Android Framework实战视频–FallbackHome结束启动Launcher篇

Android Framework实战视频–SystemServer启动FallbackHome篇

Android 8.1代码分析FallbackHome的启动:
前面已经讲解到了在startOtherService里面不仅仅会start系统服务,等系统服务都启动完成后,还会调用各个Service的systemReady方法,这里需要分析首个Ativity的启动,即常见的“Launcher”,当然是从ActivityManagerService开始分析:

public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
   //省略。。
    synchronized(this) {
       //省略。。
    synchronized (this) {
          //省略。。
        startHomeActivityLocked(currentUserId, "systemReady");
  		 //省略。。
        mStackSupervisor.resumeFocusedStackTopActivityLocked();
          //省略。。
    }
}

这里对大部分不是分析的核心代码进行了省略,这里看到了startHomeActivityLocked(currentUserId, “systemReady”);被调用,从名字既可以看得出他是要启动Home类型的Activtiy,常见的Launcher就是一种Home类型的Activity,但这里其实并不是Launcher,而是设置中的FallbackHome类型的,它也是一个Home类型的Activity,这里FallbackHome是google新加入的,主要就是因为涉及整个android系统的加密等原因,系统在还没有完全解锁前,不可以启动Launcher,因为Launcher中明显和各个第三方应用耦合较多(比如桌面可能显示着一堆的各个应用的Widget),如果直接Launcher作为FallbackHome启动,相对就会要求Launcher依赖的应用也是支持直接解密类型,那就肯定不现实。所以就先启动了FallbackHome一个什么也不显示的界面来作为启动真正Launcher的一个过度。

那来分析一下,到底是怎么启动FallbackHome,又是凭什么确定就是FallbackHome?接下来继续分析startHomeActivityLocked代码:

 boolean startHomeActivityLocked(int userId, String reason) {
	//省略
  		Intent intent = getHomeIntent();//获取Home类型的Intent
        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);//通过PackageManagerService查询出目前系统中可以匹配这个intent的ActivtiyInfo
        if (aInfo != null) {
            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
            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) {
                //省略。。
                mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
            }
        } 
        //省略。。
        return true;
    }
 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) {
        //这里是匹配HomeIntent的核心
            intent.addCategory(Intent.CATEGORY_HOME);
        }
        return intent;
    }

这里的getHomeIntent主要就是在Intent中增加 intent.addCategory(Intent.CATEGORY_HOME);即有category为Intent.CATEGORY_HOME的Intent
这里面比较简单,就是获取了HomeIntent后,然后利用intent进行ActivityInfo获取,然后判断是否还没有启动过该进程,没有则继续调用mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);调用ActivityStarter里面的startHomeActivityLocked

 void startHomeActivityLocked(Intent intent, ActivityInfo aInfo, String reason) {
        mSupervisor.moveHomeStackTaskToTop(reason);
        mLastHomeActivityStartResult = startActivityLocked(null /*caller*/, intent,
                null /*ephemeralIntent*/, null /*resolvedType*/, aInfo, null /*rInfo*/,
                null /*voiceSession*/, null /*voiceInteractor*/, null /*resultTo*/,
                null /*resultWho*/, 0 /*requestCode*/, 0 /*callingPid*/, 0 /*callingUid*/,
                null /*callingPackage*/, 0 /*realCallingPid*/, 0 /*realCallingUid*/,
                0 /*startFlags*/, null /*options*/, false /*ignoreTargetSecurity*/,
                false /*componentSpecified*/, mLastHomeActivityStartRecord /*outActivity*/,
                null /*inTask*/, "startHomeActivity: " + reason);
        if (mSupervisor.inResumeTopActivity) {
            // If we are in resume section already, home activity will be initialized, but not
            // resumed (to avoid recursive resume) and will stay that way until something pokes it
            // again. We need to schedule another resume.
            mSupervisor.scheduleResumeTopActivities();
        }
    }

这里又调用到了startActivityLocked方法:

int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
            ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
            ActivityRecord[] outActivity, TaskRecord inTask, String reason) {
//省略
        mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
                aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
                callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
                inTask);
//省略
        return mLastStartActivityResult != START_ABORTED ? mLastStartActivityResult : START_SUCCESS;
    }

又调用到了startActivity方法:

 private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
            ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
            ActivityRecord[] outActivity, TaskRecord inTask) {
     //省略
        ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
                callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
                resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
                mSupervisor, options, sourceRecord);
       //省略
        return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
                options, inTask, outActivity);
    }

又调用 startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,options, inTask, outActivity);

 private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {
//省略
            mService.mWindowManager.deferSurfaceLayout();
            result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, outActivity);
   //省略

        return result;
    }

这里又调用到startActivityUnchecked方法:

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
     
	//省略
    if (mDoResume) {
        //省略
        } else {
           //省略
            mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                    mOptions);
        }
    } 
    //省略
    return START_SUCCESS;
}

这里用会调用到ActivityStackSupervisor的resumeFocusedStackTopActivityLocked方法:
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,mOptions);

 boolean resumeFocusedStackTopActivityLocked(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
//省略
        if (targetStack != null && isFocusedStack(targetStack)) {
            return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }
//省略
        return false;
    }

这里又会调用到targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
frameworks/base/services/core/java/com/android/server/am/ActivityStack.java

 boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
     //省略
        try {
            // Protect against recursion.
            mStackSupervisor.inResumeTopActivity = true;
            result = resumeTopActivityInnerLocked(prev, options);
        } finally {
            mStackSupervisor.inResumeTopActivity = false;
        }
		//省略
        return result;
    }

又会调用到resumeTopActivityInnerLocked:

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {

//省略
        mStackSupervisor.startSpecificActivityLocked(next, true, true);
        //省略
    return true;
}

最后又会调回ActivityStackSupervisor的startSpecificActivityLocked(next, true, true):

void startSpecificActivityLocked(ActivityRecord r,
        boolean andResume, boolean checkConfig) {
//省略
    mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
            "activity", r.intent.getComponent(), false, false, true);
}

这里又会调用ActivityManagerService的startProcessLocked方法,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) {
        long startTime = SystemClock.elapsedRealtime();
    //省略

        if (app == null) {
            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
        } 
         //省略
        startProcessLocked(
                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 
                //省略
        return (app.pid != 0) ? app : null;
    }

刚开始进程ProcessRecord app肯定位null所以newProcessRecordLocked会构造一个ProcessRecord,再次调用 startProcessLocked(
app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 方法

private final void startProcessLocked(ProcessRecord app, String hostingType,
            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
        //省略。。
            boolean isActivityProcess = (entryPoint == null);
            //这里entryPoint传递的是null,所以赋值为entryPoint = "android.app.ActivityThread"
            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
          //省略
            ProcessStartResult startResult;
            if (hostingType.equals("webview_service")) {
                startResult = startWebView(entryPoint,
                        app.processName, uid, uid, gids, debugFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, null, entryPointArgs);
            } else {
              //调用process的start方法来启动进程
                startResult = Process.start(entryPoint,
                        app.processName, uid, uid, gids, debugFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, invokeWith, entryPointArgs);
            }
          //省略
    }
Android开机优化之调整Launcher的加载时间 前言 如前面两篇文章所描述的, 1、Android开机速度优化简单回顾 2、优化启动时间 我们对Android系统的开机时间优化有了一个比较全面的了解,以及一些常用的调试手段(bootchart等),在这篇文章中我们先来看看如下这个问题,首先看一张图: 如上图所示, 1、在系统启动的时候,为什么像inputmethod、phone、systemUI及settings这些包加载启动的时候要比Launcher早个2秒多的时间呢? 2、开机动画结束,到Launcher加载显示,这里存在一个2秒左 阅读详情

相关推荐

FallbackHome的启动流程(android11)

第一次执行判断为true,这里会执行,之后调用ActivityTaskManagerInternal.startHomeOnAllDisplays,这是个抽象类,我们找到他的实现类,在ActivityTaskManagerService中有个。在SystemServer的startOtherServices这个方法里他会调mActivityManagerService.systemReady这个方法,主要是执行了这里。调用resumeFocusedStacksTopActivities,之后调用。

weixin_65101089的博客 1047

Android Framework实战开发篇

广大的Android应用开发者是不是对Android系统充满着好奇,是不是很想学习Android系统开发,可惜自己学习难度又太大,本课程将手把手教你学Android Framework开发,带你走进Android系统开发的殿堂,全课程以实战为主,让你自己动手可以定制自己喜欢的Android系统,让你的Android职业道路越走越顺。学完本课程能让你学会如下知识点:-学习对BootAnimation的启动源码分析-学习对BootAnimation的opengl绘制源码分析-学习对BootAnimation的zip方式绘制源码分析-学习制作一个带有时间的显示的BootAnimation的动画-深入理解zip方式定制BootAnimation-学习android native层的posix线程实现-学习android native层封装的Threads类源码及使用-学习zygote的启动源码分析-学习zygote的进程创建过程源码分析-学习zygote启动systemserver过程分析-学习systemserver的启动分析-学习systemserver的HomeActivity的启动源码分析-学习systemserver与zygote进行socket通信创建进程源码分析-学习systemserver启动FallbackHome的Activtiy-学习FallbackHome结束及跳转Launcher源码分析-学习native c/c++层的堆栈打印

Android 13.0 屏蔽 FallbackHome 机制,并实现开机直接进入 Launcher

摘要:FallbackHome是Android系统的备用启动器,在设备加密但未解锁的directboot模式下作为临时HOME Activity运行。它监听系统解锁广播,解锁后自动跳转到真正的Launcher。通过修改WindowManagerService和ActivityRecord相关代码,系统优化了启动流程:1) 检测到真实Launcher启动时停止启动动画;2) 跳过FallbackHome可减少2-3秒黑屏时间;3) 移除了FallbackHome的启动进度UI动画。主要涉及WindowMana

u011557327的博客 1053

framework常见rom定制功能

系统rom定制对于刚入门的伙伴们来说还是有些困难的,本课程从基本的定制需求开始一点点积累项目经验的,平时项目中的经典案例会慢慢更新

android 10.0屏蔽FallbackHome 直接进入默认Launcher(去掉android正在启动弹窗)

在android 7.0以后引入了FallbackHome机制,在系统解锁之前会首选进入FallbackHome界面,等收到解锁广播以后在进入默认Launcher 这就是在进入launcher之前经常会看到 Android正在启动 的系统弹窗 客户需求去掉 Android 正在启动 提示文字 要求直接进入Launcher FallbackHome 那FallbackHome是什么呢? FallbackHome是原生setting的一个activity,且配置了DirectBoot mode。launcher

安卓兼职framework和app工程师的博客 6265

Android 10 Settings系列(二) FallbackHome 介绍

当时遇到定制需求把刚开机时显示的 Device is starting 去掉。

fighting_2017的博客 1042

Framework学习实战高级视频--SystemServer启动FallbackHome篇

课程答疑和新课信息:QQ交流群:422901085进行课程讨论 FrameWork入门课视频链接:https://edu.youkuaiyun.com/course/detail/30298 FrameWork实战课1视频链接:https://edu.youkuaiyun.com/course/detail/30275 专题博客系列: Android 8.1 zygote 启动过程源码 Android Framework实战视频–Zygote的fork进程篇 Android Framework实战视频–SystemServer启动

liaosongmao1的专栏 224

Framework定制系列(六)-----屏蔽FallbackHome手机启动中弹窗直接进入Launcher

问题场景:Android系统定制中去除锁屏KeyGuard服务之后,在系统开机进入Launcher之前,会有手机正在启动中弹窗,这部分主要涉及Settings中的FallbackHome,解决方案如下:代码路径: framework/services/core/java/com/android/server/wm/WindowManagerService.java 2. 屏蔽掉FallbackHome 代码路径:framework/services/core/java/com/android/server/

—莫言— 2277

Android高级Framework系统面试专题系列-认清楚自己的层次

Android高级系统面试之道系列-1 课程答疑和新课信息:QQ交流群:422901085进行课程讨论 FrameWork入门课视频链接:https://edu.youkuaiyun.com/course/detail/30298 FrameWork实战课1视频链接:https://edu.youkuaiyun.com/course/detail/30275 专题博客系列: Android 8.1 zygote 启动过程源码 Android Framework实战视频–Zygote的fork进程篇 Android F

learnframework的博客 696

R语言分类变量的统计描述

三篇介绍了连续变量的统计描述的R语言相关函数,计算数值的相关统计指标。本文介绍分类变量的统计描述及如何在R语言中实现。 不同于连续变量,分类变量的统计描述主要是汇总分类变量各类别例数及百分比。 1、table()函数 ...

zsc943290710的博客 1万+

2025软考中级《数据库系统工程师》案例模拟题合集

1.【说明】某销售企业正在实施电商平台项目,主要功能模块包括用户中心、商品中心、交易中心、支付中心、营销中心等。其中支付中心模块包括了一个账户表:Account (ano, aname, balance),其中属性含义分别为:账户号,账户名称和账户余额。 假设现在存在事务Ti对账户表Account进行余额的修改,系统记录了修改账户表的日志记录,假设更新日志记录表示为 <Ti,A,V1,V2>,表明事务Ti对账户A执行了一个写操作,写操作前账户A的余额是V1,写操作后账户A的余额为V2。<Ti,D

2301_76902257的博客 2328

Android高级Framework系统面试专题系列/层次定位/一线大厂腾讯阿里华为oppo面试经验

Android高级系统面试之道系列-1 课程答疑和新课信息:QQ交流群:422901085进行课程讨论 FrameWork入门课视频链接:https://edu.youkuaiyun.com/course/detail/30298 FrameWork实战课1视频链接:https://edu.youkuaiyun.com/course/detail/30275 专题博客系列: Android 8.1 zygote 启动过程源码 Android Framework实战视频–Zygote的fork进程篇 Android F

liaosongmao1的专栏 196

微信小程序网关逆向分析:从协议、签名到会话管理的安全架构剖析

在现代Web与移动应用开发中,API网关作为客户端与后端服务之间的关键通信枢纽,承担着协议转换、流量调度、安全防护与性能优化等核心职责。其工作原理通常涉及统一的请求路由、身份认证、参数校验与响应聚合。从技术价值看,深入理解网关机制不仅能帮助开发者构建更健壮、可扩展的微服务架构,还能为安全评估、性能调优与故障排查提供基础。在移动生态如微信小程序中,网关设计尤为关键,它需要处理微信特有的登录态、数据加密与防重放攻击等安全需求。本文聚焦于微信小程序网关的逆向分析方法,通过结合网络抓包与代码反编译技术,深入解析其通

weixin_29323493的博客 442

精通Android面试-腾讯阿里Android高级开发面试官选拔标准

腾讯阿里Android高级开发面试官选拔标准 课程答疑和新课信息:QQ交流群:422901085进行课程讨论 FrameWork入门课视频链接:https://edu.youkuaiyun.com/course/detail/30298 FrameWork实战课1视频链接:https://edu.youkuaiyun.com/course/detail/30275 专题博客系列: Android 8.1 zygote 启动过程源码 Android Framework实战视频–Zygote的fork进程篇 Android Frame

learnframework的博客 532

(详细总结)python爬取 163收件箱邮件内容,收件箱列表的几种方法(urllib, requests, selenium)

需求:最近有一个需求,需要将163邮箱收件箱里面的所有邮件的内容全部copy下来,整理到一个word里面,不多也就28页的邮件(不要问我为什么有这需求,不告诉你),自己手动去ctrl+ cv 的话,估计要搞吐。然后就想能不能用python的爬虫来实现,虽然过程比较苦(后期改bug改的要吐了)。但是会后还是将需求实现了。这基本也算是入门了 urllib、requests、selenium这几个py...

man_tou_22 1万+

银河麒麟v10装Docker实战:在线离线安装与容器部署指南

容器技术作为现代软件交付的核心方式,通过将应用与依赖打包成镜像,实现了环境的一致性与快速部署。Docker作为最流行的容器引擎,其安装与配置是上云和国产化转型中的基础技能。在国产操作系统银河麒麟v10环境中,由于系统兼容性和网络环境的差异,Docker的部署需要特别注意在线与离线两种模式的选择。本文从基础概念出发,结合麒麟v10的实际环境,详细梳理了Docker引擎的安装、镜像加速、存储配置以及MySQL、Redis等常用容器的部署方法,并针对SELinux、cgroup驱动等常见问题给出了解决方案,帮助开

weixin_30431445的博客 145

Android Framework 全面分析 FallbackHome

FallbackHome进程启动及Activity启动篇

qq_27494201的博客 3970

大开眼界的十大开源人工智能项目

这是一个强大的开源工具,能让你在不同框架之间自由切换,无需重写代码。它是一个开源工具,能用简单的SQL语言同时处理数据和AI模型,让一切变得有序而高效。Rasa是我开发智能聊天机器人时的首选,它让你轻松掌控机器人对话的每个细节。我经常用它快速验证模型在不同框架下的表现,省去了大量烦躁的调试过程。最近发现的Vapi是一个以API方式提供的语音AI工具,开发者友好程度超乎想象。KNIME是一个以拖拽方式构建数据分析流程的开源工具,仿佛是数据界的乐高积木。它像个忠诚的守门员,确保你的模型始终健康运行。

wjianwei666的专栏 1105

Android11 FallbackHome启动和关闭流程分析

本文简单的介绍了FallbackHome启动和关闭的代码调用流程。启动流程主要分为以下几步Systemserver进程通过socket,通知Zygote创建新进程新进程创建成功,新进程通知Systemserver可以启动FallbackHomeSystemserver通知FallbackHome,执行其生命周期FallbackHome退出的话,是接收到ACTION_USER_UNLOCKED广播,判断是否解锁并且查找到的Launcher不是自己时,就退出自己。

littleyards的博客 6235

如何快速下载Gaia DR3星表数据?中国虚拟天文台镜像站保姆级教程

本文提供了一份详细的保姆级教程,指导用户如何通过中国虚拟天文台镜像站高速、稳定地下载Gaia DR3星表数据。文章详细介绍了镜像站的访问地址、数据组织结构,并给出了使用wget、aria2c等工具进行批量下载的实战策略,帮助国内用户避开国际网络延迟,高效获取近20亿颗天体的海量数据。

weixin_29231263的博客 303

在 SAP 里玩转 FTP:标准程序 RSFTP00x 全景解析与落地实践

摘要:SAP系统通过封装的标准FTP程序(RSFTP001-008)提供便捷的文件传输能力,适用于各类集成场景。关键点包括:1)依赖SAPFTP可执行程序和RFC目的地;2)使用RSFTP005进行前置检查并生成RFC配置;3)标准报表各司其职,如RSFTP002用于命令测试、RSFTP007/008提供参考实现;4)开发时组合FTP_CONNECT/COMMAND/DISCONNECT等函数模块。特别注意前台(SAPFTP)与后台(SAPFTPA)的环境差异,这是常见故障点。该方案通过标准化工具链显著降低

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 210

Android Framework 常见解决方案(24)屏蔽FallbackHome,去除 Android正在启动,直接进入Launcher

开机以后,设备会有一个“android正在启动”这样的弹框,这个界面是一个叫FallbackHome的Activity来展示的。FallbackHome机制是Android系统启动过程中的一种降级处理机制。当系统启动时,如果默认的Launcher应用无法正常加载或出现错误,系统会自动启用FallbackHome来替代默认Launcher。但一般为了改善产品体验,最终决定移除弹窗页面,直接进入默认的Launcher,避免弹窗对用户界面的干扰。

wangdsh的博客 7963

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

FBE中的Home界面FallbackHome

FallbackHome FallbackHome继承Activity,是安卓系统启动后未解锁时的home界面。 Settings程序AndroidManifest.xml中定义了FallbackHome的intent-filter,可以看到Action:“android.intent.category.HOME”。 <!-- Triggered when user-selected home app isn't encryption aware --> &lt

qq_36063677的博客 4001

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

安卓12homeActivity的启动流程--第一次启动的是fallbackhome

然后通过resolveHomeActivity()从系统所用已安装的引用中,找到一个符合HomeItent的Activity,最终调用startHomeActivity()来启动Activity。obtainStarter() 方法返回的是 ActivityStarter 对象,它负责 Activity 的启动,一系列 setXXX() 方法传入启动所需的各种参数,最后的 execute() 是真正的启动逻辑。的startHomeOnAllDisplays()方法。

m0_46857231的博客 1730

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

android framework实战体验课

广大的Android应用开发者是不是对Android系统充满着好奇,是不是很想学习Android系统开发,可惜自己学习难度又太大,本课程将手把手教你学Android Framework开发,带你走进Android系统开发的殿堂,全课程以实战为主,让你自己动手可以定制自己喜欢的Android系统,让你的Android职业道路越走越顺。

安卓12fallbackHome结束启动launcher的流程

fallbackHome监听ACTION_USER_UNLOCKED广播,然后调用maybeFinish()方法,里面构建homeIntent,查询,如果查到的包名还是自己。所以会调用该类的onUserUnlocked方法,最终调用到ActivityTaskSupervisor.java的onUserUnlocked方法。onUserUnlocked方法里面调用了onUser(USER_UNLOCKED, userId);下面搜索USER_UNLOCKED_MSG。然后搜索START_HOME_MSG。

m0_46857231的博客 1665
上一篇: Android Framework实战视频--SystemServer启动篇
下一篇: Android Framework实战视频--FallbackHome进程启动及Activity启动篇
千里马学框架
博客等级 码龄6年 1万+粉丝 650原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里马学框架

帮助你了,就请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值