U-Boot 之一 零基础编译 U-Boot 过程详解、Image 镜像介绍及使用说明、DTB 文件使用说明

article/2025/10/24 6:43:46

  最近,工作重心要从裸机开发转移到嵌入式 Linux 系统开发,在之前的博文 Linux 之八 完整嵌入式 Linux 环境、(交叉)编译工具链、CPU 体系架构、嵌入式系统构建工具 中详细介绍了嵌入式 Linux 环境,接下来就是实际动手学习了。

  这篇博文我们仅仅关注构建过程本身,想要吃透 U-Boot,有太多东西需要学习!最开始我想放到一篇文章中,写着写着内容越来越多,最终超过了 CSDN 编辑器的限制。。。最终决定把内容拆分成多篇文章。你可能需要:

  1. U-Boot 之二 移植过程详解、 STM32F769I-EVAL 开发板适配
  2. U-Boot 之三 详解使用 eclipse + J-Link 进行编译及在线调试
  3. U-Boot 之四 构建过程(Kconfig 配置 + Kbuild 编译)详解
  4. U-Boot 之五 详解 U-Boot 及 SPL 的启动流程

源码

  文中涉及的源代码均放到了我个人的 Github 上:https://github.com/ZCShou/BOARD-STM32F769I-EVAL这个仓库中包含了要搭建的完整嵌入式 Linux 环境的所有源代码,后续博文均以该仓库中的源码为基础来学习!
在这里插入图片描述

构建环境

  我最开始使用的是 Ubuntu 20.04 LTS + Arm GNU Toolchain 10.3,前几天,我将开发环境升级为了 Ubuntu 22.04.1 LTS + Arm GNU Toolchain 11.3.Rel1-2021.10,升级后的开发环境及需要注意的问题如下所示(本文后续内容同时对新 / 旧这两个环境进行了验证)。
在这里插入图片描述

  1. 由于 Ubuntu 22.04 LTS 默认是标配 OpenSSL 3.x,而旧版 U-Boot 使用的是 OpenSSL 1.x,所以,该环境编译旧版 U-Boot(从 commit e927e21c 开始添加了相关处理) 将出现一堆警告,因此,后续使用 u-boot-v2022.10 这个版本为主:
    在这里插入图片描述
  2. Arm GNU Toolchain 10.2-2022.02 存在 BUG,导致编译 U-Boot 报错,不要使用这个版本!
    在这里插入图片描述
  3. 新版(Arm GNU Toolchain 10.3 之后的版本)的 Arm GNU Toolchain 在 Linux 上 GDB 需要 Python3.8 支持。然而,Ubuntu 22.04 默认的 Python 是 3.10。直接运行 arm-none-eabi-gdb 报错如下:
    在这里插入图片描述
    解决方法就是直接手动安装 Python3.8 即可。 旧版的 Arm GNU Toolchain 10.3 -2021.10 不需要 Python 支持
    sudo add-apt-repository ppa:deadsnakes/ppa -y
    sudo apt install python3.8
    

  此外,还有一些工具需要安装。第一个就是 GCC,GCC 就使用 Ubuntu 自带的 9.3.0 版即可。在编译 U-Boot 的过程中,我们还需要安装其他一些依赖工具,这个在后面用到的时候缺啥装啥就可以(出现各种错误的时候再安装相应工具即可)。

  这里再介绍一下安装依赖包的一些方法。正常我们应该是先使用 find 命令查找依赖是否存在。因为存在一种情况是,依赖文件本身存在但是没有在环境变量 LD_LIBRARY_PATH 里,如果不存在直接安装即可。

  1. 直接安装的情况。一般使用命令 sudo apt update -> apt-cache search xxxx -> sudo apt install xxxx,具体示例(仅仅是个示例,安装了没啥用哈)如下:
    在这里插入图片描述
    这样我们可以查看响应的依赖包的具体说明,然后根据需要来安装。
  2. 没有在环境变量 LD_LIBRARY_PATH 里的情况,目前有两种方法:
    1. 直接把依赖的动态库拷贝到上面执行的可执行命令时显示被找到的库的目录下。
    2. 把依赖的动态库所在的目录添加到环境变量 LD_LIBRARY_PATH 里:export LD_LIBRARY_PATH=/path_to_lib/:/lib/x86_64-linux-gnu/:$LD_LIBRARY_PATH

运行环境

  我使用的嵌入式环境是 STM32F769I-EVAL 板子。STM32F769I-EVAL 板子使用的 STM32F769NI 这个 MCU,STM32F769NI 这款 MCU 采用的是 ARM Cortex-M7 的核心,指令集架构是 ARMv7m。此外,还需要注意,这个板子上的的串口的 RX 默认是断开,需要用短路帽连接起来。
在这里插入图片描述
  U-Boot 本身没有提供对于 STM32F769I-EVAL 板子的支持,但是它支持的 STM32F769-Disco 板子。STM32F769-Disco 开发板与 STM32F769I-EVAL 评估板的 MCU 都使用的是 STM32F769NI,因此,我们直接编译后下载是可以运行的。

  不过两者的板载资源不同(例如,DRAM 大小),因此,U-Boot 识别的某些外设信息是不对的。这里仅仅关注如何进行零基础编译,在博文 U-Boot 之二 移植过程详解、 STM32F769I-EVAL 开发板适配 中我详细介绍了如何将 U-Boot 移植到 STM32F769I-EVAL 板子。

编译过程

  在开始编译之前,我们先介绍两个命令:make clean 用于清空编译中间文件 和 make distclean 用于清除所有编译产生的文件。如果我们想要重新编译,可以使用以上两个命令清理环境(这两个命令在 U-Boot 根目录的 Makefile 中有详细的定义,在博文 U-Boot 之四 构建过程(Kconfig 配置 + Kbuild 编译)详解 中会有说明)。

  1. 第一步肯定是获取 U-Boot 的源代码,我这里直接使用了当前最新存档版:u-boot-2021.10.tar.bz2。这里需要重点注意,我最开始直接使用 Git 获取了最新的源代码,结果编译之后运行直接 HardFault,分析好久没找到原因,最后决定使用一个稳定发布版试试,结果没有问题。。。
    在这里插入图片描述
      成功下载并解压源代码之后(注意我这里将解压后的文件名命名为了 u-boot),我们需要进入 u-boot 目录下,使用命令:cd u-boot。此后就在 u-boot 目录下进行各种操作。

  2. 第二步就是生成配置,直接使用命令:ARCH=arm CROSS_COMPILE=arm-none-eabi- make O=build_stm32 stm32f769-disco_defconfig其中,参数 O=xx 用于指定编译的输出路径,这样,所有编译输出都放到指定目录下,方便查看。 不出意外的话会出现以下错误:

    1. /bin/sh: 1: bison: not found
      在这里插入图片描述
        这个错误是由于我们没有安装 bison 这个工具。Bison 是一个通用解析器生成器。GUN 软件之一,官网 https://www.gnu.org/software/bison/。Ubuntu 下直接使用命令:sudo apt install bison 即可(这个不是最新版,如果需要最新版需要自己从源码安装)。

    2. /bin/sh: 1: flex: not found
      在这里插入图片描述
        这个错误是由于我们没有安装 flex 这个工具。flex 是一个词法分析器。用来将一个 .l 文件生成一个 .c 程序文件。源代码托管于 Github:https://github.com/westes/flex。Ubuntu 下直接使用命令:sudo apt install flex 即可。

    3. 正常完成如下所示:
      在这里插入图片描述

  3. 第三步修改配置(裁剪)。直接使用命令:ARCH=arm CROSS_COMPILE=arm-none-eabi- make O=build_stm32 menuconfig其中,参数 O=xx 用于指定编译的输出路径,这样,所有编译输出都放到指定目录下,方便查看。 不出意外的话会出现以下错误:

    1. Unable to find the ncurses package
      在这里插入图片描述
        这个错误是由于我们没有安装 ncurses 这个工具。ncurses(new curses)是一套编程库,它提供了一系列的函数以便使用者调用它们去生成基于文本的用户界面。GUN 软件之一,官网:https://invisible-island.net/ncurses/。Ubuntu 下直接使用命令:sudo apt install libncurses-dev 即可。安装成功之后,重新 make menuconfig,就会进入下面的界面:
      在这里插入图片描述
      我们需要做的就是选择其中的 SPL / TPL 菜单项,然后回车,在其中下翻页找到 Activate Falcon Mode 项(SPL / TPL ---> Activate Falcon Mode),按 n 将选择去掉,然后保存退出。
      在这里插入图片描述
        其中还有很多项,这个就需要根据自己需要来具体进行裁剪了。当然有个前提是,修改了配置很大可能还需要配套修改对应的源代码,因为之所以修改肯定是为了适应自己开发板。
    2. Your display is too small to run Menuconfig!
      在这里插入图片描述
      这个错误提示很明显,就是终端界面太小,把终端拖大一些就好了。
  4. 第四步就是真正的编译了,直接使用命令:ARCH=arm CROSS_COMPILE=arm-none-eabi- make O=build_stm32 -j$(nproc)其中,参数 O=xx 用于指定编译的输出路径,这样,所有编译输出都放到指定目录下,方便查看。 不出意外的话会出现以下错误:

    1. /bin/sh: 1: arm-none-eabi-gcc: not found
      在这里插入图片描述
        这个错误是由于我们没有安装 GCC for ARM 导致的。也就是没有编译 U-Boot 使用的编译器。解决方法也非常简单,就是安装 GCC for ARM 即可。

        这里有个需要注意的点,如果大家搜索 Ubuntu 下安装 GCC for ARM,很多文章都过推荐使用 apt 命令来安装,类似于:sudo apt-get install gcc-arm-none-eabi,这个版本并不是最新的(貌似使用这个旧版本也可以,我选择了使用最新版)。更重要的是,ARM 之前已经宣布不再更新 Launchpad 上的 GCC for ARM 了(具体见 Launchpad 上的说明)。 其只在 ARM 的官网提供编译好的压缩包及源代码的压缩包。

      这里简单来讲解一下直接从 ARM 官网下载压缩包的安装方法:

      1. 下载最新版的 Linux x86_64 Tarball。目前最新的是 gcc-arm-none-eabi-10.3-2021.10-x86_64-linux.tar.bz2 。GCC for ARM 下载地址:https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads

      2. 将压缩包解压。我这里将其解压到了 /opt/ 目录下。直接使用命令:tar -xjvf gcc-arm-none-eabi-10.3-2021.10-x86_64-linux.tar.bz2 -C /opt。等待解压完成,/opt/gcc-arm-none-eabi-10.3-2021.10 目录下就是最新的 GCC for ARM 的各种可执行程序、库等文件了。

      3. 此时我们需要将 /opt/gcc-arm-none-eabi-10.3-2021.10 添加到系统环境变量这样才能正常在终端中使用各种命令。具体有两种方法(我采用了第二种):

        1. 第一种是创建符号连接
          sudo ln -s /opt/gcc-arm-none-eabi-your-version/bin/arm-none-eabi-gcc /usr/bin/arm-none-eabi-gcc 
          sudo ln -s /opt/gcc-arm-none-eabi-your-version/bin/arm-none-eabi-g++ /usr/bin/arm-none-eabi-g++
          sudo ln -s /opt/gcc-arm-none-eabi-your-version/bin/arm-none-eabi-gdb /usr/bin/arm-none-eabi-gdb
          sudo ln -s /opt/gcc-arm-none-eabi-your-version/bin/arm-none-eabi-size /usr/bin/arm-none-eabi-size
          
        2. 第二种是在 .bashrc 文件(在 Linux 系统普通用户目录(cd /home/xxx)或 root 用户目录(cd /root)下,用指令 ls -al 可以看到该隐藏文件,一般使用用户目录下的即可)最后面增加以下内容:
          # GCC for ARM
          export PATH="$PATH:/opt/gcc-arm-none-eabi-10.3-2021.10/bin"
          
      4. 可能需要重启我们之前已经打开的终端以上配置才会生效。

      5. 这里有一点需要注意,通过压缩包安装不能解决依赖关系,需要我们自己运行尝试,看看少啥安啥。目前已知的依赖是 ncures5(会报错:error while loading shared libraries: libncurses.so.5)和 libncursesw5(报错:error while loading shared libraries: libncursesw.so.5: cannot open shared object file: No such file or directory),其需要安装 sudo apt install libncurses5 libncursesw5(貌似应该是需要 32 位的,我们上面安装的 libncurses-dev 应该是 64 位的)。 在这里插入图片描述
        至于需不需要其他的依赖,大家自行尝试,我这里是没有提示需要其他任何组件。

    2. fatal error: openssl/evp.h:
      在这里插入图片描述
      这个错误主要是由于 U-Boot 代码使用了 openssl 中的相代码,而我们的环境中没有安装 openssl。Ubuntu 下直接使用命令:sudo apt install libssl-dev 即可。

  5. 正常编译完成之后。我们需要的文件就有了。我们真正需要的是根目录下的 u-boot.bin 和 spl 目录下的 u-boot-spl.bin
    在这里插入图片描述

  6. 其他一些问题。我在试用 make CHANGELOG 命令时出现错误 unrecognized command line option ‘-mno-unaligned-access’,不知道为啥,也没找到如何解决。

    最新的 U-Boot-v2022.07 版本已经没有该错误了
    在这里插入图片描述

Image 镜像

  成功编译之后,就会在 U-Boot 源码的根目录下产生多个可执行二进制文件以及编译过程文件,这些文件都是 u-boot.xxx 的命名方式。这些文件由一些列名为 .xxx.cmd 的文件生成,.xxx.cmd 这些文件都是由编译系统产生的用于处理最终的可执行程序的。注意,下面部分文件可能没有与自己的 make menuconfig 中的配置有关系。
在这里插入图片描述

  • u-boot: 这个文件是编译后产生的 ELF 格式的最原始的 U-Boot 镜像文件,后续的文件都是由它产生的!.u-boot.cmd 这个命令脚本描述了如何产生。
    在这里插入图片描述
  • u-boot-nodtb.bin: 这文件是使用编译工具链的 objcopy 工具从 u-boot 这个文件中提取来的,它只包含可执行的二进制代码。就是把 u-boot 这个文件中对于执行不需要的节区删除后剩余的仅执行需要的部分。由 .u-boot-nodtb.bin.cmd 这个命令脚本产生。
    在这里插入图片描述
  • u-boot-dtb.bin:u-boot-nodtb.bin 尾部拼接上设备树后形成的文件。由 .u-boot-dtb.bin.cmd 这个命令脚本产生。
    在这里插入图片描述
  • u-boot.bin: 就是把 u-boot-dtb.bin 重命名得到的。由 .u-boot.bin.cmd 这个命令脚本产生。
    在这里插入图片描述
  • u-boot.img:u-boot.bin 开头拼接一些信息后形成的文件。由 .u-boot.img.cmd 这个命令脚本产生。
  • u-boot-dtb.img:u-boot.bin 开头拼接一些信息后形成的文件。由 .u-boot-dtb.img.cmd 这个命令脚本产生。
  • u-boot.srec: S-Record 格式的镜像文件。由 .u-boot.srec.cmd 这个命令脚本产生。
  • u-boot.sym: 这个是从 u-boot 中导出的符号表文件。由 .u-boot.sym.cmd 这个命令脚本产生。
  • u-boot.lds: 编译使用的链接脚本文件。由 .u-boot.lds.cmd 这个命令脚本产生。
  • u-boot.map: 编译的内存映射文件。该文件是有编译工具链的连接器输出的!
  • System.map: 记录 U-Boot 中各个符号在内核中位置,但是这个文件是使用了 nmgrep工具来手动生成的
    在这里插入图片描述
  • u-boot.dtb: 这个是编译好的设备树二进制文件。就是 ./dts/dt.dtb 重命名得到的。./dts/dt.dtb 来自于 arch/arm/dts/stm32f769-eval.dtb 重命名。

  默认是开启了 SPL 的,因此,在编译 U-Boot 时会额外单独编译 SPL,编译产生的镜像文件就存放在 ./SPL 目录下。这下面的镜像生成方式与 U-Boot 基本是一模一样的。

  • u-boot-spl: 这个文件是编译后产生的 ELF 格式的 SPL 镜像文件,后续的文件都是由它产生的!.u-boot-spl.cmd 这个命令脚本描述了如何产生。
  • u-boot-spl-nodtb.bin: 这文件是使用编译工具链的 objcopy 工具从 u-boot-spl 这个文件中提取来的,它只包含可执行的二进制代码。就是把 u-boot-spl 这个文件中对于执行不需要的节区删除后剩余的仅执行需要的部分。由 .u-boot-spl-nodtb.bin.cmd 这个命令脚本产生。
  • u-boot-spl-dtb.bin:u-boot-nodtb.bin 尾部依次拼接上 u-boot-spl-pad.binu-boot-spl.dtb 后形成的文件。由 .u-boot-spl-dtb.bin.cmd 这个命令脚本产生。
  • u-boot-spl.bin: 就是把 u-boot-dtb.bin 重命名得到的。由 .u-boot-spl.bin.cmd 这个命令脚本产生。
  • u-boot-spl.sym: 这个是从 u-boot 中导出的符号表文件。由 .u-boot-spl.sym.cmd 这个命令脚本产生。
  • u-boot-spl.lds: 编译使用的链接脚本文件。由 .u-boot-spl.lds.cmd 这个命令脚本产生。
  • u-boot-spl.map: 编译 SPL 的内存映射文件。
  • u-boot-spl.dtb: 这个是编译好的设备树二进制文件。就是 ./dts/dt.dtb 重命名得到的。./dts/dt.dtb 来自于 arch/arm/dts/stm32f769-eval.dtb 重命名。
  • u-boot-spl-pad.bin: 应该是对齐使用的数据,具体为啥需要这个还没找到。

Image 使用

  编译之后,源码的根目录下会生成一堆二进制的文件(.bin),其中,在默认的 U-Boot 配置下,我们实际需要的 U-Boot 实际包含两部分:spl/u-boot-spl.binu-boot.bin。而且,默认情况下,编译的这俩文件是可以直接在 MCU 内部的 Nor Flash 中运行的。
在这里插入图片描述
  因此,我们可以直接使用 J-link 等调试器将这俩文件烧写到 Flash 中。至于烧写地址,在 U-Boot 源码中(具体见于 ./config/stm32f769-disco_defconfig./include/configs/stm32f746-disco.h)都是配置好了的。

设备树

  设备树源文件被最终编译为二进制的 DTB 文件,原始的 DTB 文件位于 arch/arm/dts/xxx.dtb 下面,构建系统会复制到 ./dts/dt.dtb,进一步重命名为 ./u-boot.dtb。u-boot 支持两种形式将 dtb 编译到 u-boot 的镜像中:

  • dtb 和 u-boot 的 bin文件分离

    • 需要打开 CONFIG_OF_SEPARATE 宏来使能。
    • 在这种方式下,u-boot 的编译和 dtb 的编译是分开的,先生成 u-boot 的 bin 文件,然后再另外生成dtb 文件。
    • dtb 最终会自动追加到 u-boot 的 bin 文件的最后面。因此,可以通过 u-boot 的结束地址符号,也就是 _end 符号来获取 dtb 的地址。
  • dtb 集成到 u-boot 的 bin 文件内部

    • 需要打开 CONFIG_OF_EMBED 宏来使能。
    • 在这种方式下,在编译 u-boot 的过程中,也会编译 dtb。
    • 最终 dtb 是包含到了u-boot 的 bin 文件内部的。dtb 会位于 u-boot 的 .dtb.init.rodata 段中,并且在代码中可以通过 __dtb_dt_begin 符号获取其符号。

    官方不推荐这种方式,建议仅用于调试

  • 另外,也可以通过 fdtcontroladdr 环境变量来指定 dtb 的地址。可以通过直接把 dtb 加载到内存的某个位置,并在环境变量中设置 fdtcontroladdr 为这个地址,达到动态指定 dtb 的目的。

参考

  1. https://askubuntu.com/questions/1243252/how-to-install-arm-none-eabi-gdb-on-ubuntu-20-04-lts-focal-fossa
  2. https://james-hui.com/2021/07/02/building-a-small-uboot-linux-and-rootfs-for-arm-cortex-m7/
  3. opdenacker-understanding-u-boot-falcon-mode.pdf
  4. https://adrianalin.gitlab.io/popsblog.me/posts/build-linux-for-stm32f769i-disco-using-buildroot/

http://chatgpt.dhexx.cn/article/oxQeOnUl.shtml

相关文章

dts、dtb的那些事儿

笔者最近在支持新的案子,过于忙碌,好久没更新了,勿怪。 1、设备树大变革故事 2011年3月17日的ARM Linux邮件列表有封邮件“this whole ARM thing is a fucking pain in the ass”引起了轩然大波,原来是我们的Linux之父Linus Torv…

DBT工具简介

What is DBT 在将数据加载到集中式数据仓库之前,必须对其进行清理、保持一致并根据需要进行组合。换句话说,必须转换数据,这就是我们所谓的 ETL(提取、转换、加载)和 ELT 中的“T”。 这是挖掘数据价值的关键一步。 而…

4.2uboot对设备树的支持——dtb的修改原理

本节说明在uboot中修改dtb的原理。 在uboot中,有一些命令支持对dtb文件进行修改。 当我们想要修改dtb文件时,可以直接修改dts文件,然后编译dts文件生成新的dtb文件,再将新的dtb文件载入设备。 或者,我们也可以在ubo…

DBT是什么

关于DBT DBT 是一种数据转换工作流,可帮助您完成更多工作,同时产生更高质量的结果。您可以使用 dbt 来模块化和集中分析代码,同时还为数据团队提供软件工程工作流中常见的护栏。在将数据模型安全部署到生产环境之前,通过监控和可见…

2.1设备树的规范(dts和dtb)——DTS格式

本节学习设备树的规范。 使用设备树时,需要编写dts文件,然后使用dtc编译dts文件,生成dtb文件。 所以本节分为两部分,第一部分讲解dts格式,第二部分讲解dtb格式。 首先看一下dts文件的布局。 DTS文件布局&#xff0…

关于EMUELC适配各种机型,DTB如何修改教程

很多爱好者留言,都想问关于EMUELC的dtb适配机型问题,这里我就出一个教程,如何修改dtb,然后去适配自己的机型,然后启动 。这里我只是提供方法,具体的调试是需要原理图进行配置。 首先,不管是aml…

DTBO简介

1、DTBO简介 设备树 (DT) 是用于描述“不可发现”硬件的命名节点和属性构成的一种数据结构。操作系统(例如在 Android 中使用的 Linux 内核)会使用 DT 来支持 Android 设备使用的各种硬件配置。硬件供应商会提供自己的 DT 源文件,接下来…

【DTB/DTBO 分区介绍】

如果你的 DTB/DTBO 位于专属的分区(例如 dtb 和 dtbo 分区)中,请使用以下表格结构和头文件格式: 数据结构 dt_table_header 仅适用于 dtb/dtbo 分区;您不能在kernel( image.gz) 末尾处附加此格式。如果您有一个 DTB/D…

2.2设备树的规范(dts和dtb)——DTB格式

本节讲述设备树的dtb格式。 上节讲述了dts格式。回顾上节,在dts文件和dtsi文件中,可以使用C语言的define和include,使用方法和作用也同C语言相同。 编写dts文件后,需要使用dtc工具将dts文件编译成dtb文件。dtc工具可以检查dts文…

「设备树」dtb给内核的两种工作模式

一,传递dtb给内核 对于传统bootloader提供两种工作模式:一是启动加载模式(start loading),一是下载模式(downloading) 工作在启动加载模式时,bootloader会自动执行bootcmd命令&#…

设备树_dtb文件分析

前言:我之前的原计划是没有打算写设备树dtb文件分析,但是情势所迫啊!,学习还是要一步一步来的。 在前面的章节提到过.dts文件以文本方式对系统设备树进行描述,经过Device Tree Compiler(dtc)将dts文件转换成二进制文件…

Linux设备树学习2 - DTB文件格式

一. DTB文件简介 DTB文件是由DTS文件通过dtc命令编译生成的二进制文件。DTS文件不能直接被内核解析,需要编译成DTB文件才可以直接被内核识别并解析使用的。 二. DTB文件内容布局 从上图可以看出,DTB由四个部分组成,分别是struct fdt_header&a…

setUserVisibleHint-- fragment真正的onResume和onPause方法

这个情况仅适合与多个fragment之间切换时统计,而非activity和fragment同时交互,因当时项目为首页4个fargment时长统计,因此适合,经下面网友评论指出,特在这里写出此问题,因最近项目较忙,具体情况…

onCreate与onStart区别,onStart与onResume区别

http://www.cnblogs.com/kofi1122/archive/2011/04/10/2011772.html Activity生命周期之我见 关于Activity生命周期的文章很多,而且大部分也说得很详细,所以作为关于这方面的内容我本来不想多说,但是大家可能跟我之前一样,在看这方…

Flutter BaseWidget 实现onResume、onPause()

熟读唐诗三百首,不会作诗也会吟。——孙洙 最近用Flutter开发的项目算是完成了开发到上线第一阶段了。任何一个项目开始了,若想追求的是更好,那么就需要下功夫对项目用户体验和代码效率深入的研究了。作为用户和产品经理、老板、UI、不懂技术…

Activity生命周期中onStart()和onResume()的区别

Activity生命周期中onStart()和onResume()的区别 在讲onStart()和onResume()的区别之前,必须清楚Activity的四种状态: 1.Running状态:一个新的Activity的启动入栈后,它在屏幕最前端,处于栈的最顶端,此时它…

android Activity的onPause()与onResume()

官方文档地址:http://www.android-doc.com/training/basics/activity-lifecycle/pausing.html#Resume Pause和Resume一个Activity 在一般的app使用中,前台的activity一般是会被视觉组件所遮住的,这就会导致activity的pause。举个例子&#x…

android中onResume、onPause等方法

程序正常启动:onCreate()->onStart()->onResume(); 正常退出:onPause()->onStop()->onDestory() 程序按back 退出: onPause()->onStop()->onDestory(),再进入:onCreate()->onStart()->onResume(); 程序按…

OnStart()方法和OnResume()方法的区别

文章目录 一、Activity的生命周期简述在讲onStart()和onResume()的区别之前,必须清楚Activity的四种状态: 二、OnStart()和OnResume()方法的区别区别: 总结 一、Activity的生命周期简述 在讲onStart()和onResume()的区别之前,必须…

简单介绍几种Java后台开发常用框架组合

01 前言 Java框架一直以来都是面试必备的知识点,而掌握Java框架,不管在成熟的大公司,快速发展的公司,还是创业阶段的公司,都能对当前正在开发中的系统有整体的认知,从而更好的熟悉和学习技术,这…