Android Framework实战视频--FallbackHome进程启动及Activity启动篇

android8.1启动过程(九) SystemServer启动FallbackHome SystemServer进程在启动的过程中会启动PackageManagerService,PackageManagerService启动后会将系统中的应用程序安装完成。在此前已经启动的AMS会将Launcher启动起来。 Launcher的入口为AMS的systemReady方法 ActivityManagerDebugConfig frameworks/base/services/core/java/com/android/server/am/ActivityManagerDebugConfi.. 阅读详情
AI摘要

本文详细解析了Android应用进程如何通过Zygote启动,包括ZygoteProcess的start方法、参数传递、子进程创建与Activity启动流程,重点剖析了ActivityThread的main方法和关键步骤。

课程答疑和新课信息: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实战视频–FallbackHome进程启动及Activity启动篇

android 8.1 源码中FallbackHome进程启动及Activity启动分析

上一节课已经一步步分析到了Process.start了,那本节就是来分析Process的start方法具体是怎么一步步的把进程启动及进程启动后对应的Activity是怎么启动的

1 应用进程的创建

首先看Process.start的源码:

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 invokeWith,
                                  String[] zygoteArgs) {
        return zygoteProcess.start(processClass, niceName, uid, gid, gids,
                    debugFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
    }

这里调用了ZygoteProcess的start方法:

 public final Process.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 invokeWith,
                                                  String[] zygoteArgs) {
        try {
            return startViaZygote(processClass, niceName, uid, gid, gids,
                    debugFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
        } catch (ZygoteStartFailedEx ex) {
            Log.e(LOG_TAG,
                    "Starting VM process through Zygote failed");
            throw new RuntimeException(
                    "Starting VM process through Zygote failed", ex);
        }
    }

这里调用到了startViaZygote方法:

private Process.ProcessStartResult startViaZygote(final String processClass,
                                                      final String niceName,
                                                      final int uid, final int gid,
                                                      final int[] gids,
                                                      int debugFlags, int mountExternal,
                                                      int targetSdkVersion,
                                                      String seInfo,
                                                      String abi,
                                                      String instructionSet,
                                                      String appDataDir,
                                                      String invokeWith,
                                                      String[] extraArgs)
                                                      throws ZygoteStartFailedEx {
        ArrayList<String> argsForZygote = new ArrayList<String>();

        // --runtime-args, --setuid=, --setgid=,
        // and --setgroups= must go first
        argsForZygote.add("--runtime-args");
        argsForZygote.add("--setuid=" + uid);
        argsForZygote.add("--setgid=" + gid);
       //省略
        synchronized(mLock) {
            return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
        }
    }

这里设置了一系列参数后,在调用zygoteSendArgsAndGetResult

 private static Process.ProcessStartResult zygoteSendArgsAndGetResult(
            ZygoteState zygoteState, ArrayList<String> args)
            throws ZygoteStartFailedEx {
        try {
           //省略
            final BufferedWriter writer = zygoteState.writer;
            final DataInputStream inputStream = zygoteState.inputStream;

            writer.write(Integer.toString(args.size()));
            writer.newLine();

            for (int i = 0; i < sz; i++) {
                String arg = args.get(i);
                writer.write(arg);
                writer.newLine();
            }

            writer.flush();

            // Should there be a timeout on this?
            Process.ProcessStartResult result = new Process.ProcessStartResult();

            // Always read the entire result from the input stream to avoid leaving
            // bytes in the stream for future process starts to accidentally stumble
            // upon.
            result.pid = inputStream.readInt();
            result.usingWrapper = inputStream.readBoolean();

            if (result.pid < 0) {
                throw new ZygoteStartFailedEx("fork() failed");
            }
            return result;
        } catch (IOException ex) {
            zygoteState.close();
            throw new ZygoteStartFailedEx(ex);
        }
    }

zygoteSendArgsAndGetResult这里就调用了BufferedWriter的writer对象进行了socket的写入数据,writer就是zygoteState.writer,
那zygoteState.writer又具体是怎么赋值的呢?

   public static ZygoteState connect(String socketAddress) throws IOException {
            DataInputStream zygoteInputStream = null;
            BufferedWriter zygoteWriter = null;
            final LocalSocket zygoteSocket = new LocalSocket();

            try {
            //连接zygote进程的serversocket
                zygoteSocket.connect(new LocalSocketAddress(socketAddress,
                        LocalSocketAddress.Namespace.RESERVED));
				//socket中的输入流
                zygoteInputStream = new DataInputStream(zygoteSocket.getInputStream());

				//socket中的输出流
                zygoteWriter = new BufferedWriter(new OutputStreamWriter(
                        zygoteSocket.getOutputStream()), 256);
            } catch (IOException ex) {
                try {
                    zygoteSocket.close();
                } catch (IOException ignore) {
                }

                throw ex;
            }

            String abiListString = getAbiList(zygoteWriter, zygoteInputStream);
            Log.i("Zygote", "Process: zygote socket " + socketAddress + " opened, supported ABIS: "
                    + abiListString);

            return new ZygoteState(zygoteSocket, zygoteInputStream, zygoteWriter,
                    Arrays.asList(abiListString.split(",")));
        }

这里面的socketAddress是如下代码赋值的:

public static final ZygoteProcess zygoteProcess =
        new ZygoteProcess(ZYGOTE_SOCKET, SECONDARY_ZYGOTE_SOCKET);
public static final String ZYGOTE_SOCKET = "zygote";

也就是ZYGOTE_SOCKET变量,变量就是前几节课讲的zygote进程创建的Server名字
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java中的main方法中:

  String socketName = "zygote";

所以就是这样ActivtiyManagerService通过socket与zygote进行一个跨进程通信。

在这里插入图片描述
ActivityManagerService这边把要创建一个进程的主要参数等需要准备好,然后发送给zygote端,zygote端接受到了发来数据后创建对应的进程。创建对应进程时候还会执行传过来的entryPoint即 "android.app.ActivityThread"类的main方法
接下来看看分析之前Zygote部分的接受和创建进程,前面zygote已经知道,zygote本身是一直循环执行runSelectLoop里面的While:

 Runnable runSelectLoop(String abiList) {
//省略; 

        while (true) {
  			 //省略; 
            for (int i = pollFds.length - 1; i >= 0; --i) {
                if ((pollFds[i].revents & POLLIN) == 0) {
                    continue;
                }

                if (i == 0) {
                //如果是本身serverSocket的fd有输入消息,则保存住新建连接的客户端peer和fd,比如:第一次AMS就需要绑定
                    ZygoteConnection newPeer = acceptCommandPeer(abiList);
                    peers.add(newPeer);
                    fds.add(newPeer.getFileDesciptor());
                } else {
                    try {
                    //如果哪个peer或者fd有消息了,则processOneCommand读取里面消息
                        ZygoteConnection connection = peers.get(i);
                        final Runnable command = connection.processOneCommand(this);
                        if (mIsForkChild) {
                         //省略
                            return command;
                        } 
        }
    }

所以核心在processOneCommand方法:

 Runnable processOneCommand(ZygoteServer zygoteServer) {
        String args[];
        Arguments parsedArgs = null;
        FileDescriptor[] descriptors;

        try {
        //读取发送过来的参数
            args = readArgumentList();
            descriptors = mSocket.getAncillaryFileDescriptors();
        } 
        //省略
        parsedArgs = new Arguments(args);
      //省略
      //根据参数创建对应的进程,这里本质和以前分析system server进程创建一样
        pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
                parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
                parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.instructionSet,
                parsedArgs.appDataDir);

        try {
            if (pid == 0) {
			 //省略
                return handleChildProc(parsedArgs, descriptors, childPipeFd);
            } 
            //省略
    }

这里processOneCommand创建好了进程后,又调用handleChildProc方法:
private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors,
FileDescriptor pipeFd) {
//省略
//这里最后调用ZygoteInit.zygoteInit和以前systemserver其实是一样的,只不过这里的remainingArgs参数变成ActivityThread
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs,
null /* classLoader */);

}

/这里最后调用ZygoteInit.zygoteInit和以前systemserver其实是一样的,只不过这里的remainingArgs参数变成ActivityThread类,返回的ActivityThread的main方法执行的Runable

2 应用进程的Activity启动

当应用进程被创建后,最开始就是执行的ActivityThread的main方法

 public static void main(String[] args) {
    //省略
        Process.setArgV0("<pre-initialized>");

        Looper.prepareMainLooper();
		//创建ActivityThread对象,并且调用attach方法
        ActivityThread thread = new ActivityThread();
        thread.attach(false);

        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }

        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }

        // End of event ActivityThreadMain.
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

这里主要就是对loop进行初始化,接下来再创建ActivityThread对象,调用它的attach方法:

 private void attach(boolean system) {
        if (!system) {
           //省略
            RuntimeInit.setApplicationObject(mAppThread.asBinder());
            final IActivityManager mgr = ActivityManager.getService();
            try {
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
          //省略
        }
        //省略
    }

这里主要应用端会获取system server中的AMS对象IBinder对象,然后调用attachApplication(mAppThread)方法,这个attachApplication真正实现那是在ActivityManagerService:

 @Override
    public final void attachApplication(IApplicationThread thread) {
        synchronized (this) {
         //省略
            attachApplicationLocked(thread, callingPid);
           //省略
        }
    }

这里又调用重载方法:private final boolean attachApplicationLocked(IApplicationThread thread,
int pid);

 private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) {
		//省略
     			//跨进程调用,执行对应进程的Application的onCreate等方法
                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
                        null, null, null, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.persistent,
                        new Configuration(getGlobalConfiguration()), app.compat,
                        getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial);
           //省略。。
 
                if (mStackSupervisor.attachApplicationLocked(app)) {

			//省略。。
        return true;
    }

这里调用StackSupervisor.attachApplicationLocked(app):

   boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
				//省略
                            if (realStartActivityLocked(activity, app,
                                    top == activity /* andResume */, true /* checkConfig */)) {
                                didSomething = true;
                            }
                  //省略
        return didSomething;
    }
这里又会调用到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,
                        // TODO: Have this take the merged configuration instead of separate global
                        // and override configs.
                        mergedConfiguration.getGlobalConfiguration(),
                        mergedConfiguration.getOverrideConfiguration(), r.compat,
                        r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
                        r.persistentState, results, newIntents, !andResume,
     //省略

        return true;
    }

这里最后跨进程调回应用进程,ActivityThread的ApplicationThread的scheduleLaunchActivity方法,这个方法再进行Activtiy的onCreate等调用,这里就不带大家分析ActivityThread的相关内容了,因为ActivityThread中基本属于应用层自己执行代码,而且相对不那么复杂,自己完全可以分析,所以当作作业留给大家自己分析接下来的ActivityThread部分。
最后附上对应的流程总图:
在这里插入图片描述

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

相关推荐

Android系统开机动画结束进入launcher前黑屏优化

最近在做一个项目,发现系统开机在开机动画结束后会有6S的黑屏才进入launcher界面,严重影响使用体验。

weixin_43479637的博客 3368

Android系统_开机流程_解析

一、简介 众所周知,Android系统的本质是一个基于Linux系统的、自由且开放源代码的应用程序,它的启动和运行都是依托Linux系统为内核而实现的,因此,Android 系统的启动流程主要包括Linux内核启动和Android框架启动两大阶段。   二、Linux内核启动  1、 加载内核引导程序bootloader 当电源按下,引导芯片代码开始从预定义的模块开始执行,加载引

Jon.Lo 的专栏 1425

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 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优化之启动页去黑屏实现秒启动

前言 还记得之前我们写了一篇文章,基于RxJava实现酷炫启动页,然而当我们点击桌面图标启动APP时,有时会闪一下黑色背景,有时黑色背景时间还比较长,哎呀,难看死了,这个怎么办捏,别方,我们今天就来看看启动页的优化。 一、消除启动时的黑屏 点击桌面launcher图标启动APP,闪现的黑色背景其实是出现在我们看到界面第一帧之前。那我们就要想办法让这个黑色的背景变成用户喜欢看到的画面或者让它透明化。有了思路方法也就粗现了,我们有下面两种方案: 自定义WelcomActivity的Theme 说白了,就是把出现的黑屏通过android:windowBackground属性设置为我们想要的背景。

从图片到3D模型:用Tripo+Unity打造AI建模流水线(避坑指南)

本文详细介绍了如何利用Tripo和Unity构建AI驱动的3D建模流水线,从图片到3D模型的高效转换。通过文生模型和图生模型的双模系统,开发者可以大幅提升建模效率,适用于游戏开发和数字内容创作。文章还提供了环境配置、图片预处理、批量生成等实用技巧,帮助开发者避开常见陷阱。

weixin_27024175的博客 614

framework常见rom定制功能

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

FUEL算法解读(一)——框架解读,思维导图可以很清晰看懂算法启动框架,已更新完,图太大放不上来链接在文末

一图看懂FUEL算法节点框架!!!

weixin_43793717的博客 2785

Android Framework实战视频--FallbackHome结束启动Launcher篇

Android Framework实战视频–FallbackHome结束启动Launcher篇 Android 8.1代码分析FallbackHome结束启动Launcher篇: 1、FallbackHome的结束 上一讲已经分析到了FallbackHome Activity的启动,但其实FallbackHome只是系统由未解密到解密过程的一个过度界面,只要用户把系统解锁过一次后,那么就一直会把系统的Home变成Launcher,这个时候FallbackHome的使命就已经完成,不会再出现了。所以经常用户会

learnframework的博客 5951

谷歌(Google) Pixel 8/9 Pro(xl)如何获取 root 权限

谷歌(Google)Pixel8/9Pro(xl)等系列手机破解后,会在你的init_boot.img同路径生成一个magisk_patched.img,把这个文件拷贝到adb目录下,稍后还得把它刷回手机,这样手机才能获得Root权限,因为安卓14、15以后的内核结构调整,和Pixel7及以下的6、5、4、3、2等系列手机破解稍微不一致。因为ROOT权限的获取,需要使用ROM中的内核文件,个人强烈建议在官网下载ROM,直接刷最新版,其他地方的ROM如果没有校验码,请自行斟酌是否使用。

bugsycrack的博客 3486

三维Copula建模进阶:从对称、嵌套到Pair-Copula(C-Vine/D-Vine)到底怎么选?

本文深入探讨三维Copula建模的进阶策略,包括对称Archimedean、嵌套结构和Vine Copula(C-Vine/D-Vine)的选择方法。通过对比数学特性、计算复杂度和实际应用案例,提供了一套针对金融风险分析等场景的决策框架,帮助分析师根据数据特征选择最优模型。

weixin_27038701的博客 436

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

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

learnframework的博客 3950

海思Hi3061M MCU:为高速吹风筒市场注入智能动力

此外,海思还提供了丰富的软件开发工具和生态环境组件,帮助开发者快速实现复杂功能。高速吹风筒因其高效的风力和快速的干燥效果,近年来在市场上越来越受欢迎。然而,传统的高速吹风筒在性能、噪音和使用寿命等方面仍有改进的空间。凭借其高性能、低功耗、低噪声和易用的开发工具,为高速吹风筒市场带来了全新的解决方案。这不仅提高了用户的使用体验,还延长了电机的使用寿命。这不仅减少了电机的电磁噪声,还提高了电机的运行效率。还支持风机顺逆风启动适配多种电阻范围的电机,进一步提高了吹风筒的适用性和灵活性。

2401_83448585的博客 2016

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

避坑指南:用逐飞开源库驱动MT9V03X摄像头时容易忽略的3个细节(附TFT显示优化技巧)

本文详细解析了在智能汽车竞赛中使用MT9V03X摄像头(总钻风)时常见的硬件连接、图像采集和TFT显示优化问题。重点介绍了逐飞开源库中容易被忽略的三个关键细节,包括电源管理、看门狗设置和中断优先级配置,并提供了针对IPS200和TFT180显示屏的优化技巧,帮助参赛队伍提升图像处理效率和显示质量。

study的专栏 744

37、基于视觉的轻量级面部呼吸和心率测量技术

本文提出了一种基于视觉的轻量级面部呼吸和心率测量技术,通过远程光电容积脉搏波描记法(RPPG)和面部振动信息实现非接触式生理信号采集。创新性地结合框选和特征点选择多个感兴趣区域(ROI),并采用光流跟踪、主成分分析(PCA)和集成经验模态分解(EEMD)等方法优化信号处理流程。实验结果表明,该方法在测量精度和稳定性方面优于传统方法,并可在树莓派4等低功耗平台上实现实时运行,具有广泛的应用前景。

r7s8t的博客 307

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

华为OD机试 新系统真题 【数字系统转换器】

华为OD机试 新系统真题【数字系统转换器】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试真题【数字系统转换器】多语言题解。

qq_45776114的博客 542

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

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

精通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

老版QQ原生表情gif动态

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

Android Framework 全面分析 FallbackHome

FallbackHome进程启动及Activity启动篇

qq_27494201的博客 3970

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

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

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

wangdsh的博客 7963

Android11 FallbackHome启动和关闭流程分析

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

littleyards的博客 6235

安卓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 10 替换默认Launcher或开机引导app后,可能会引起首次开机黑屏(FallbackHome界面)一段时间,才会加载显示界面

因为公司新做的项目是基于android 10系统做的产品,需要更换一些原生的app,最新更新了一些app之后发现首次刷机后开机动画播完会进入一个黑屏界面,过10s左右才会进入开机引导界面,就抓log分析发现当前是FallbackHome,可看dumpsys 信息,如下 $ adb shell dumpsys activity activities | grep Resume state=RESUMED stopped=false delayedResume=false finishin...

u012959605的专栏 5582

Android11 以Window的视角来看FallbackHome的启动

所以经过以上的调用流程,创建了一个home Task,其实home Task就是ActivityStack对象,然后挂载到DefaultTaskDisplayArea下。注释1处,parent为前面创建的FallbackHome Task,mStartActivity为前面创建的ActivityRecord,将ActivityRecord设置为FallbackHome Task的孩子。注释1处创建FallbackHome Task,mTargetStack为前面创建的home Task。

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

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

打赏作者

千里马学框架

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

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

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

打赏作者

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

抵扣说明:

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

余额充值