• 搭建Android源码工作环境


    • 简单介绍系统架构、编译环境的搭建
    • 简单介绍利用 AndroidStudio 调试 system_process 进程的方法及编译更新部分系统模块的方式

    Android系统架构

    Android 系统架构如下两图所示:
    在这里插入图片描述

    • 应用框架。应用框架最常被应用开发者使用。很多此类 API 都可以直接映射到底层 HAL 接口,并可提供与实现驱动程序相关的实用信息。
    • Binder IPC。Binder 进程间通信 (IPC) 机制允许应用框架跨越进程边界并调用 Android 系统服务代码,这使得高级框架 API 能与 Android 系统服务进行交互。在应用框架级别,开发者无法看到此类通信的过程,但一切似乎都在“按部就班地运行”。
    • 系统服务。系统服务是专注于特定功能的模块化组件,例如窗口管理器、搜索服务或通知管理器。应用框架 API 所提供的功能可与系统服务通信,以访问底层硬件。Android 包含两组服务:“系统”(诸如窗口管理器和通知管理器之类的服务)和“媒体”(与播放和录制媒体相关的服务)。
    • 硬件抽象层 (HAL)。HAL 可定义一个标准接口以供硬件供应商实现,这可让 Android 忽略较低级别的驱动程序实现。借助 HAL,硬件开发者可以顺利实现相关功能,而不会影响或更改更高级别的系统。HAL 实现会被封装成模块,并会由 Android 系统适时地加载。如需了解详情,请参阅硬件抽象层 (HAL)
    • Linux 内核。开发设备驱动程序与开发典型的 Linux 设备驱动程序类似。Android 使用的 Linux 内核版本包含一些特殊的补充功能,例如低内存终止守护进程(一个内存管理系统,可更主动地保留内存)、唤醒锁定(一种 PowerManager 系统服务)、Binder IPC 驱动程序,以及对移动嵌入式平台来说非常重要的其他功能。这些补充功能主要用于增强系统功能,不会影响驱动程序开发。可以使用任意版本的内核,只要它支持所需功能(如 Binder 驱动程序)即可。不过建议使用 Android 内核的最新版本。如需了解详情,请参阅构建内核一文。

    以上部分内容来源: https://source.android.google.cn/devices/architecture?hl=zh-cn

    搭建开发环境并编译源码

    本节将讨论 Android 11 源码下载和编译的方法、AndroidStudio开发环境的搭建方法,及 system_process 进程的调试方法等相关知识。

    选择分支

    可参考 source.android.google.cn 的文档 代号、标记和 Build 号 ,可以看到当前最新的版本及标记如下:

    Build标记版本支持的设备安全补丁程序级别
    RQ2A.210305.007android-11.0.0_r33Android11
    RQ1D.210105.003android-11.0.0_r28Android11Pixel 3、Pixel 3 XL、Pixel 4a (5G)、Pixel 52021-01-05
    RQ1A.210105.003android-11.0.0_r27Android11Pixel 3、Pixel 3 XL、Pixel 4、Pixel 4a (5G)、Pixel 4 XL、Pixel 52021-01-05
    RQ1A.210105.002android-11.0.0_r26Android11Pixel 3a、Pixel 3a XL、Pixel 4a2021-01-05

    参考代码仓库中的最新Tag,我们选择 android-11.0.0_r33

    搭建Android构建环境

    构建环境的搭建可参考官方的 搭建构建环境 文档,以下结合实际搭建过程中遇到的问题简要进行介绍。

    构建环境要求

    首先需要机器满足一些要求,一般来说,需要:

    • 操作系统: Linux 或者 macOS
    • 内存: 16GB的可用RAM/交换空间
    • 硬盘: 检出代码至少250GB可用磁盘空间,如果需要构建,则还需要150GB

    从Android8.0 开始,可以使用源码中带的Dockerfile来构建一个镜像用于编译aosp源码;下面我们将分别介绍如何构建编译用的Docker镜像及直接在macOS11.2上搭建构建环境,构建时根据情况任选一种即可。

    提示:

    最新的构建要求可以参考官方文档 aosp源码构建要求

    搭建构建环境-Docker

    docker镜像基于ubuntu:18.04,所以ubuntu上也可以按照dockerfile中的命令配置环境

    这里假设安装了Docker,如果没有安装,可以参考Docker官方安装文档进行安装。

    mkdir docker
    cd docker
    
    • 1
    • 2

    将如下内容保存为Dockerfile,并存储到之前建立的docker目录

    FROM ubuntu:18.04
    
    ARG userid
    ARG groupid
    ARG username
    
    RUN apt-get update \
        && apt-get install -y git-core gnupg flex bison build-essential zip \
        curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev \
        x11proto-core-dev libx11-dev lib32z1-dev libgl1-mesa-dev libxml2-utils xsltproc unzip fontconfig \
        python3 \
        && rm -rf /var/lib/apt/lists/* 
        
    # 最新的AOSP源码中已经带了JDK,所以无需安装
    # RUN curl -o jdk8.tgz https://android.googlesource.com/platform/prebuilts/jdk/jdk8/+archive/master.tar.gz \
    #  && tar -zxf jdk8.tgz linux-x86 \
    #  && mv linux-x86 /usr/lib/jvm/java-8-openjdk-amd64 \
    #  && rm -rf jdk8.tgz
    
    RUN curl -o /usr/local/bin/repo https://storage.googleapis.com/git-repo-downloads/repo \
     && chmod a+x /usr/local/bin/repo \
     && ln -s /usr/bin/python3 /usr/bin/python
    
    RUN groupadd -f -g $groupid $username || true \
     && useradd -m -u $userid -g $groupid $username \
     && echo $username >/root/username \
     && echo "export USER="$username >>/home/$username/.gitconfig
    COPY gitconfig /home/$username/.gitconfig
    RUN chown $userid:$groupid /home/$username/.gitconfig
    ENV HOME=/home/$username
    ENV USER=$username
    ENTRYPOINT chroot --userspec=$(cat /root/username):$(cat /root/username) / /bin/bash -i
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    以上dockerfile基于源码中 build/make/tools/docker/Dockerfile 修改

    构建镜像:

    # Copy your host gitconfig, or create a stripped down version
    $ cp ~/.gitconfig gitconfig
    $ docker build --build-arg userid=$(id -u) --build-arg groupid=$(id -g) --build-arg username=$(id -un) -t android-build-bionic .
    
    • 1
    • 2
    • 3

    使用镜像:

    可以直接使用我已经构建好的镜像: hanlyjiang/android-build-bionic,可以使用如下命令拉取并修改tag:

    docker pull hanlyjiang/android-build-bionic

    docker tag hanlyjiang/android-build-bionic android-build-bionic:latest

    假设aosp的源码目录位于 ~/aosp

    # 设置变量指向源码顶层目录
    ANDROID_BUILD_TOP=~/aosp
    # 如自行构建镜像,此处
    BUILD_IMAGE=android-build-bionic
    cd $ANDROID_BUILD_TOP
    # 运行容器,并将aosp源码目录挂载到容器内部的/src目录
    docker run -it --rm --name aosp-builder -v $PWD:/src $BUILD_IMAGE
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    启动成功后就会进入容器的shell中,之后在容器中进行执行对应的编译命令即可。

    docker使用提示:

    1. 上面的docker run 命令中添加了 --rm 选项,在启动的交互式bash结束后就会自动移除容器。之后需要再次输入docker run命令启动容器;为了避免每次都输入如上命令启动容器,可以移除--rm 选项
    2. 我们执行构建一般需要较长时间,期间如果我们退出容器的bash,则构建任务会终止,这显然不是我们想要的,我们可以通过 ctrl+P ctrl+Q 命令告诉docker我们需要关闭容器到本机的输入输出重定向,但是并不暂停任何执行的任务。之后再使用 docker attach aosp-builder(aosp-builder是我们启动时指定的容器名称) 即可重新将容器输入输出重定向到本机终端,继续与容器内的shell交互。

    搭建构建环境-macOS11.2

    这里介绍下macOS(x86)编译的环境配置

    1. 准备源码目录

      由于macOS默认的分区是不区分大小写的,但是aosp编译需要区分大小写,所以需要创建一个区分大小写的分区,这里可以有两种选择:

      1)使用另外一个磁盘(如外置的移动硬盘),然后使用磁盘工具将其抹掉为区分大小写的分区;

      2)创建一个区分大小写的磁盘映像,可通过如下命令执行

      hdiutil create -type SPARSE -fs 'Case-sensitive Journaled HFS+' -size 250g ~/android.dmg.sparseimage
      
      # 定义装载卸载函数
      mountAndroid() { hdiutil attach ~/android.dmg.sparseimage -mountpoint /Volumes/android; }
      umountAndroid() { hdiutil detach /Volumes/android; }
      # 装载刚刚创建的磁盘映像到 /Volumes/android 目录,之后cd 到此目录执行即可
      mountAndroid
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
    2. 安装 xcode 命令行工具

      xcode-select --install
      
      • 1
    3. 设置bash

      # 可加入到~/.bash_profile 文件中
      ulimit -S -n 2048
      
      • 1
      • 2
    4. 下载 10.15 SDK

      从此处下载: https://github.com/phracker/MacOSX-SDKs/releases

      下载完成后放入到此目录:/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/

    5. 修复代码(在下载完成源码之后执行)

      • 编辑文件 system/core/base/cmsg.cpp

      • 添加一行:size_t psize = getpagesize();

        namespace base {
            
        size_t psize = getpagesize();
            
        ssize_t SendFileDescriptorVector(borrowed_fd sockfd, const void* data, size_t len,
        
        • 1
        • 2
        • 3
        • 4
        • 5
      • 将文件中所有 PAGE_SIZE 替换为 psize

    参考:

    下载源码

    安装Repo

    提示: 先前构建的docker镜像中已经安装了repo,如使用镜像,可跳过此步骤

    mkdir ~/.bin
    PATH=~/.bin:$PATH
    
    # 这里可能需要开启代理
    curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
    chmod a+x ~/bin/repo
    
    # 验证是否安装成功
    repo help
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    输出如下则表示安装成功:

    usage: repo COMMAND [ARGS]
    
    repo is not yet installed.  Use "repo init" to install it here.
    
    The most commonly used repo commands are:
    
      init      Install repo in the current working directory
      help      Display detailed help on a command
    
    For access to the full online help, install repo ("repo init").
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    获取aosp源码底包

    wget https://mirrors.tuna.tsinghua.edu.cn/aosp-monthly/aosp-latest.tar
    # 解压
    tar xf aosp-latest.tar
    
    • 1
    • 2
    • 3

    或者直接下载:

    mkdir aosp ; cd aosp 
    repo init -u https://android.googlesource.com/platform/manifest -b android-11.0.0_r33
    
    • 1
    • 2

    然后执行代码同步命令:

    repo sync -c -j16
    
    • 1

    repo sync 命令说明:

    • 通过 -c 指定只获取当前分支
    • 通过 -j16 指定并行获取的线程数量,这里我电脑为8核,所以指定了16个线程

    提示:

    代码下载完成后,我们复制一份到另外一个目录只用于浏览代码 rsync -a -H --progress aosp aosp-ro

    编译源码

    首先, 我们使用 repo 启动一个工作分支

    repo start dev_android11_r33 --all
    
    • 1

    初始化环境:

    source build/envsetup.sh
    
    • 1

    envsetup.sh 脚本会导入若干命令,可使用 hmm 查看完整的可用命令列表。

    选择目标:

    lunch aosp_x86_64-eng
    
    • 1

    输出如下:

    $ lunch aosp_x86_64-eng
    ============================================
    PLATFORM_VERSION_CODENAME=REL
    PLATFORM_VERSION=11
    TARGET_PRODUCT=aosp_x86_64
    TARGET_BUILD_VARIANT=eng
    TARGET_BUILD_TYPE=release
    TARGET_ARCH=x86_64
    TARGET_ARCH_VARIANT=x86_64
    TARGET_2ND_ARCH=x86
    TARGET_2ND_ARCH_VARIANT=x86_64
    HOST_ARCH=x86_64
    HOST_OS=darwin
    HOST_OS_EXTRA=Darwin-20.3.0-x86_64-11.2.3
    HOST_BUILD_TYPE=release
    BUILD_ID=RQ2A.210305.007
    OUT_DIR=out
    PRODUCT_SOONG_NAMESPACES=device/generic/goldfish device/generic/goldfish-opengl hardware/google/camera hardware/google/camera/devices/EmulatedCamera device/generic/goldfish device/generic/goldfish-opengl
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    构建:

    make -j16
    
    • 1

    提示:构建命令可参考 官方文档-编译 Android

    构建成功后输出如下:

    [100% 119047/119047] Create system-qemu.img now
    removing out/target/product/generic_x86_64/system-qemu.img.qcow2
    out/host/darwin-x86/bin/sgdisk --clear out/target/product/generic_x86_64/system-qemu.img
    
    #### build completed successfully (14:34:15 (hh:mm:ss)) ####
    
    • 1
    • 2
    • 3
    • 4
    • 5

    我们这里使用模拟器进行运行

    emulator
    
    • 1

    运行起来之后,查看其中的系统版本号如下:

    20210403135316

    使用AndroidStudio调试 system_process

    本小节介绍如何使用AS来调试Android Java Framework的核心进程 system_process。

    下载安装AndroidStudio

    AndroidStudio官方页面下载安装运行即可

    生成AS项目配置

    总的流程如下:

    • 全量编译一次aosp源码
    • 编译development/tools/idegen 生成 idegen.jar 文件;
    • 使用development/tools/idegen/idegen.sh 生成AS项目配置
    • 使用AndroidStudio打开生成的配置,导入源码项目

    其中 idegen.sh 仅是简单的使用java执行idegen.jar,idegen.jar 会在源码根目录生成androidstudio使用的两个文件,即android.imlandroid.ipr,生成过程中会读取 excluded-paths 文件,该文件中可以使用正则表达式定义过滤规则,该文件会从三个路径去读取:

    • development/tools/idegen/excluded-paths
    • vendor/google/excluded-paths
    • 源码根目录的 excluded-paths

    所以我们只需要将自己的过滤规则定义到源码根目录的 excluded-paths文件中即可。

    android.iml 中有三种xml配置:

    1)sourceFolder;

    1. excludeFolder;

    2. orderEntry;

    idegen.jar 在执行时会根据配置的规则自动写入这三种规则,其中sourceFolder用于指定源码目录-即as会将其作为源码导入,excludeFolder用于指定排除目录-即as压根不会去搜索任何文件,也不会对其中的文件建立索引,orderEntry 则一般用于指定依赖的jar文件;

    在idegen.jar的逻辑中:

    • 没有被过滤规则匹配到的目录都会尝试去其中搜寻java及jar文件,只有在其中找到了源码文件,才会被加入到sourceFolder中。
    • 过滤规则中配置的目录,只有其中有java及jar文件时,才会被加入到excludeFolder配置中。
    • 如果目录中找到了java文件,会去读取java文件,自动确认sourceFolder的开始路径,以保证路径能正确匹配包名,如:有个目录de vice/test/src/java/android/Test.java,其中Test.java的包为android,那么sourceFolder的路径会自动设置为de vice/test/src/java/

    修改idegen代码并编译idegen.jar

    修改 development/tools/idegen 模块代码及配置

    1. src/Log.java 为了方便我们查看生成的过程,打开debug日志开关

      class Log {
      
          static final boolean DEBUG = true;
          
          // ...
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
    2. src/IntelliJ.java , 这里由于代码中书写错误,prebuilt 实际上在源码中并不存在,我们手动将其修改为 prebuilts

              sourceRootsXml.append("<excludeFolder url=\"file://$MODULE_DIR$/out/target/product\"/>\n");
      // 修改这一行 prebuilt --> prebuilts
              sourceRootsXml.append("<excludeFolder url=\"file://$MODULE_DIR$/prebuilts\"/>\n");
      
      
      • 1
      • 2
      • 3
      • 4
    3. 编译生成 idegen.jar

      # 在源码根目录执行
      source build/envsetup.sh
      cd development/tools/idegen
      mm -j16
      
      • 1
      • 2
      • 3
      • 4

      成功生成后输出如下:

      [100% 228/228] Install: out/host/darwin-x86/framework/idegen.jar
      #### build completed successfully (05:30 (mm:ss)) ####
      
      • 1
      • 2

    手动获取java文件

    手动获取AIDL生成的java文件

    我们通过如下命令将aidl生成的java文件拷贝到 源码根目录的idea/aidl/src目录下

    croot
    mkdir -p idea/aidl/src
    find out/soong/.intermediates/frameworks/base/api-stubs-docs-non-updatable/android_common/gen/aidl -name "*.srcjar" | xargs -I {} unzip {} -d idea/aidl/src
    
    • 1
    • 2
    • 3
    获取生成的资源
    cp -R out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/aapt2/R idea/framework-res_R
    
    • 1

    编辑排除规则并生成配置

    1. 在项目根目录中添加一个 excluded-paths 文件,输入如下内容(一行作为一个匹配规则,规则的格式按Java中Pattern类的规则编写)

      # 几个根目录的规则
      ^art/.*
      ^packages/.*
      ^bootable/.*
      ^build/.*
      ^cts/.*
      ^dalvik/.*
      ^developers/.*
      ^external/.*
      ^platform_testing/.*
      ^pdk/.*
      ^sdk/.*
      ^system/.*
      ^test/.*
      
      # platform-compat中有注解的类
      ^tools/(?!(platform-compat))
      ^development/.*
      ^device/.*
      ^prebuilts/*
      
      # 这里我们查看这两个模块,所以注释掉
      #^libcore/.*
      #^frameworks/.*
      # 关于out其他的一些规则
      ^out/soong/.intermediates/(?!((frameworks)|(libcore)))
      # ./out/soong/.intermediates/frameworks/native/libs/binder/libbinder/android_x86_64_shared/gen/aidl/android/os/BnServiceManager.h
      # ^out/soong/.intermediates/.*
      ^out/target/.*
      
      # 根据实际运行情况补充的规则
      # 移除可能的jar
      # 如 ./frameworks/base/tools/aapt2/integration-tests/CommandTests/android-28.jar
      ^frameworks/base/tools/aapt2/.*\.jar
      ^frameworks/base/tests
      ^libcore/support/src/test
      ^libcore/luni/src/test
      gradle-wrapper.jar
      
      # 对于sdk源码的隐藏,我们exclude掉,以使可以找到真正的源码
      ^libcore/ojluni/annotations
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
    2. 生成iml文件,执行下面命令生成

      development/tools/idegen/idegen.sh
      
      • 1

      完成后根目录下即生成了android.iml,android.ipr

    导入到AndroidStudio

    androidstudio 配置

    1. 配置jvm选项,根据机器实际情况设置vm分配的内存策略
      在这里插入图片描述

      -Xmx16g
      -Xms2g
      
      • 1
      • 2
    2. 配置 idea 属性
      在这里插入图片描述

      # 大小写敏感(macOS)
      idea.case.sensitive.fs=true
      
      idea.max.intellisense.filesize=100000
      
      • 1
      • 2
      • 3
      • 4

    导入项目到AS并配置

    配置sdk主要是为了避免查看或调试代码时,AS仍然去使用SDK中配置的class,而不是我们的aosp中的java源码。

    1. 使用AndroidStudio 打开项目根目录下 android.ipr 文件即可导入项目;

    2. 配置项目SDK,进入项目设置,添加一个新的JDK,并删除所有依赖jar库,我们这里取名为:1.8 (No Libraries)

      20210402095209

    3. 配置项目SDK,进入项目设置,添加一个新的SDK,并删除所有jar库,对应的JDK选择之前创建的1.8 (No Libraries),这里我们将SDK命名为 Android API 30 Platform-NoLib

      20210402095255

    4. 在Project设置中,选择项目SDK为之前设置的 Android API 30 Platform-NoLib

      20210402095343

    5. 进入项目设置-模块设置,将模块的SDK设置为之前设置的 Android API 30 Platform-NoLib
      在这里插入图片描述

    附加调试器到 system_process

    1. 附加调试器到 system_process 进程

    20210402093915
    在这里插入图片描述

    1. 成功后的Debugger界面如下所示

      20210402100639

    2. 打断点测试,这里我们选择在 Binder.java 文件中添加断点,然后在模拟器中打开相机APP以触发断点逻辑。下图就表示我们到达了断点,说明我们可以通过AS来调试该进程了。

    在这里插入图片描述

    提示:附加调试器时,如找不到设备,可参考第5小节中的 错误解决:Debug中不显示设备

    修改并更新系统模块

    在调试分析过程中,可能我们需要修改一下其中内容以协助分析,可以按如下方式进行。

    Framework

    构建 framework 分两块:

    1. JAR 部分使用命令 mmm frameworks/base/
    2. 资源部分: mmm frameworks/base/core/res/

    安装:

    # 获取root权限
    adb root
    adb disable-verity
    adb reboot
    adb remount
    # 移除旧的framework
    adb shell
    cd /system/framework/
    rm framework-res.apk
    exit
    
    # 推入新的framework
    adb push out/target/product/<device_targeted>/system/framework/framework-res.apk /system/framework/
    
    # 重启服务
    adb reboot
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    packages中app

    • 构建
    cd ~/aosp
    source build/envsetup.sh 
    lunch aosp_x86_64-eng
    # 重新构建单个模块 (如 Dialer)
    mmm packages/apps/dialer/
    # 生成的文件会在控制台中输出来
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 更新到系统
    adb install -r out/target/product/<device_targeted>/system/priv-app/<app_name>/<app_name>.apk
    adb reboot
    
    • 1
    • 2

    SystemUI

    • 编译
    cd WORKING_DIRECTORY
    source build/envsetup.sh
    # 选择设备
    lunch 31
    # 重新构建SystemUI
    mmm frameworks/base/packages/SystemUI/
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 安装到系统
    adb install -r out/target/product/<device_targeted>/system/priv-app/SystemUI/SystemUI.apk
    adb reboot
    
    • 1
    • 2

    使用提示及常见错误

    使用提示:项目源码浏览配置

    筛选Project代码范围

    1. 点击project窗口的设置按钮,选择 “Edit Scopes”

      20210402104239

    2. 新建一个规则,输入名称,并在Pattern中输入过滤规则: file[android]:frameworks//*||file[android]:libcore//*
      在这里插入图片描述

    过滤VCS配置中不必要的模块

    打开VCS配置,移除frameworks和libcore之外的所有其他模块

    20210402105446

    使用提示:导入其他模块的源码到AS

    不建议直接修改 android.iml 文件,应当通过修改源码根目录自定义的 excluded-paths 文件中定义的规则来包含其他模块的源码。

    修改此文件后,重新执行 development/tools/idegen/idegen.sh 来生成最新的as项目配置。生成完成后一般as如果是打开状态,会自动更新索引,如果索引更新有问题,可关闭项目,然后重新打开。

    错误解决:macOS .DS_Store 导致打包镜像失败

    编译基本完成,但是最后打包system.img文件时报错,报错内容如下:

    set_selinux_xattr: No such file or directory searching for label "/.DS_Store"
    e2fsdroid: No such file or directory while configuring the file system
    
    10:00:38 ninja failed with: exit status 1
    
    • 1
    • 2
    • 3
    • 4

    解决方式:删除源码目录中的所有 .DS_Store,可通过如下命令进行统一清理

    find . -name ".DS_Store"  | xargs -I {} rm {} 
    
    • 1

    说明: .DS_Store 文件为macOS中存储文件夹界面展示相关的一些信息,在Finder中查看对应目录后可能会生成

    错误解决:附加调试器时不显示设备

    在附加调试器时,可能会如下图一样,模拟器已经启动了,但是附加调试器的窗口中设备列表中没有设备

    在这里插入图片描述

    此时检查自己的项目配置中的SDK是否选择了AndroidSDK,设置成 Android SDK 即可

    20210402121537

    错误解决:模拟器无法启动-报找不到内核版本信息

    当使用 android-11.0.0_r28 版本时,编译通过后,使用emulator启动时,报出如下错误

    emulator: ERROR: Can't find 'Linux version ' string in kernel image file: /Volumes/HIKVISION/google-aosp/out/target/product/generic_x86_64/kernel-ranchu
    
    • 1

    原因是emulator版本过旧,需要使用新的emulator,执行如下命令获取新的版本:

    cd prebuilts/android-emulator
    # 查询可用分支,https://android.googlesource.com/platform/prebuilts/android-emulator/+refs
    git fetch aosp android-11.0.0_r33:refs/remotes/m/android-11.0.0_r33
    # 检出分支
    git co -b android-11.0.0_r33 refs/remotes/m/
    android-11.0.0_r33
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    获取完成后再次执行 emulator 命令

    emulator -version
    # Android emulator version 30.3.0.0 (build_id 6946397) (CL:N/A)
    emulator 
    # 启动模拟器
    
    • 1
    • 2
    • 3
    • 4

    参考文章

    参考:

  • 相关阅读:
    methods,计算属性和监视
    前端 JS 经典:Math 常用方法汇总
    面试题精讲:你所不知道的Lambda表达式和常用的函数式接口
    java基于微信小程序的加油站加油服务系统uni-app
    多线程和网路编程写的客户端和服务端的交流
    【Spring Boot系列】- Spring Boot事务应用详解
    矩阵分析与应用+张贤达
    linux下nginx重启命令
    883. 三维形体投影面积
    自动驾驶 3D点云深度学习与实践 三 基于Voxel的3D深度学习(VoxelNet,SECOND,PointPillar)
  • 原文地址:https://blog.csdn.net/mospuito/article/details/124994219