Android 与其他基于 Linux 的系统有何不同?

Android 与其他基于 Linux 的系统有何不同?

文章目录

概述Linux KernelAOSP安卓构建系统rootfs 组织和分区布局安卓 C 库为什么 Android 不使用 BusyBox?安卓初始化系统安卓守护进程安卓日志系统硬件访问和 Android HALAndroid 框架和系统服务安卓应用Android 是不是 Linux 发行版?

原文:https://embeddedbits.org/what-differs-android-from-other-linux-based-systems/

如果您是嵌入式 Linux 开发人员但从未使用过嵌入式 Android,那么本文适合您。如果您开发或维护 Linux 发行版,并且我想开始开发 Android 发行版,那么本文适合您。如果您是一名 Android 应用程序开发人员并想了解一些 Android(内部)的工作原理,本文也适合您。如果你只是好奇,这篇文章也适合你!😃

我们将从构建系统到分区布局,从 rootfs 的内容到操作系统组件的架构,从 IPC/RPC 机制到硬件访问如何工作的不同角度来比较 GNU/Linux 系统和 Android。

概述

如果您查看任何嵌入式 Linux 系统的架构,您总会发现相同的主要组件:

一个或多个引导加载程序用于引导、配置硬件和引导 Linux 内核。Linux 内核。包含库和应用程序的根文件系统 (rootfs)。

如果现在您查看基于 Android 的系统的相同图表,会有什么区别?

引导程序就在那里。Android 不需要任何特殊的引导加载程序,尽管人们通常会添加对fastboot 的支持,这是谷歌为用户和开发人员创建的协议,用于与基于 Android 的系统上的引导加载程序进行交互。Linux 内核也在那里,但有“一些”变化。稍后再谈。根文件系统也在那里。但它真的不一样!没有什么像来自 Debian 的典型根文件系统或来自 Buildroot 或 OpenEmbedded 的定制 rootfs。

从上图我们可以看出,Android 用户空间组件清楚地分为三个主要层:

Native:这是所有本机 (C/C++) 应用程序和库所在的位置。之所以称为Native,是因为它在 ART 虚拟机之外运行。本机层主要用于将 Linux 内核接口抽象到框架层。Framework:这是实现所有操作系统服务的地方(主要是在 Java 中)。对操作系统资源的访问通过称为系统服务的组件(远程)公开,使用称为 Binder 的 IPC/RPC 机制。API 将抽象应用程序对这些系统服务的访问。Application:通常用Java或Kotlin编写,他们只是看到暴露的操作系统API。

在详细研究 Android 用户空间组件之前,让我们先谈谈内核。

Linux Kernel

要运行基于 Android 的系统,我们需要在 Linux 内核中启用一些额外的“功能”。如果我尝试讨论大多数功能,这篇文章会太长,但我可以评论一些:

Binder:这是Android中使用的IPC(Inter-Process Communication)和RPC(Remote Procedure Call)机制。您可以与 DBUS 做一个粗略的比较,但 DBUS 在用户空间中运行,而 Binder 是一种更快、更轻的基于内核的实现。Ashmem:Android 中的默认共享内存分配器(Google 不喜欢 POSIX SHM)。低内存杀手:建立在内核OOM(内存不足)杀手之上的逻辑,与守护进程(lmkd)结合,有助于在低内存情况下管理系统。 大多数这些特性已经在主线内核中可用,但如果你想要“Androidisms”的完整列表,你可以克隆谷歌的内核通用存储库并搜索以“ANDROID:”开头的提交:

$ git clone https://android.googlesource.com/kernel/common kernel-common

$ git checkout remotes/origin/android11-5.4

$ git log --oneline | grep "ANDROID:" | less

5427f8b72fc0 ANDROID: GKI: update xiaomi symbol list

ecb88922f521 ANDROID: GKI: update Vivo symbol list

32b242337266 ANDROID: sysrq: add vendor hook for sysrq crash information

42e516f6b23b ANDROID: ABI: update allowed list for galaxy

de198b0f2d39 ANDROID: GKI: update Vivo symbol list

$ git log --oneline | grep "ANDROID:" | wc -l

1157

尽管 Linux 内核中有这些(以及其他一些)主要变化,Android 在用户空间组件及其架构(所谓的 Android 平台)方面确实与 GNU/Linux 系统不同,Android 平台的源代码是在名为AOSP(Android 开源项目)的项目中提供。

AOSP

AOSP 由数百个存储库(特别是 Android 11 中的 780 个)组成,您可以在https://android.googlesource.com/ 中查看所有这些存储库。

源代码是用已知的工具管理的,比如repo和git,它是巨大的!Android 11 是 100GB 的源代码加上一次构建后的 115GB。因此,您确实需要大量磁盘空间来处理 Android 源代码。

克隆最新的 AOSP 源代码就像运行以下两个命令一样简单(可以在repo init 中使用-b来克隆特定的Android 发布标记或分支):

$ repo init -u https://android.googlesource.com/platform/manifest

$ repo sync

几个小时后,您的机器中将拥有 Android 源代码:

$ ls

Android.bp dalvik libcore read-snapshot.txt

art developers libnativehelper sdk

bionic development Makefile system

bootable device out test

bootstrap.bash external packages toolchain

build frameworks pdk tools

compatibility hardware platform_testing

cts kernel prebuilts

作为一个开源项目,有多个讨论组与社区和开发者进行交流,任何人都可以通过Gerrit 代码审查工具为项目做出贡献。

绝大多数软件组件在 Apache 和 BSD 许可下,一些软件组件在 GPL/LGPL 许可下,一些谷歌应用程序是闭源的(例如谷歌播放、Gmail、谷歌地图、YouTube 等)。这些应用程序在名为Google 移动服务(GMS)的软件包中提供,要获取它们,您需要通过Android 兼容性计划(ACP)对设备进行认证。

当我们下载 AOSP 源代码时,与其他嵌入式 Linux 开发方法相比,我们可以看到一些差异。

与现成的发行版(例如 Debian)不同,您可以轻松下载完整的源代码并从头开始构建发行版(例如,如果您想创建一个自定义的 Debian 系统,您通常从预编译的包中完成) )。

与构建系统方法(例如 Buildroot、OpenEmbedded)相比,在 Android 中,我们似乎有一个使用repo sync命令下载的“大应用程序” 。当然这不是真的。我们在那里有数以千计的项目和存储库,它们最终将组成操作系统映像。而将所有内容放在一起的责任在于 Android 构建系统…

安卓构建系统

在以前的 Android 版本中,构建系统完全基于 makefile,其中编译每个软件组件的指令在Android.mk文件中定义。下面是在 Android 中构建“Hello World”C 应用程序的Android.mk文件示例:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_SRC_FILES = helloworld.c

LOCAL_MODULE = helloworld

LOCAL_MODULE_TAGS = optional

include $(BUILD_EXECUTABLE)

基于 Makefile 的构建系统有几个缺点,包括增量构建的性能低下,并且在最新版本的 Android 中被Soong 构建系统取代。

在 Soong 构建系统中,编译软件组件的规则在 Blueprint 文件 ( Android.bp )中定义,其语法类似于 JSON。以下是在 Android 中构建“Hello World”C 应用程序的相同示例,但使用的是蓝图文件:

cc_binary {

name: "helloworld",

srcs: ["helloworld.c"],

tags: ["optional"],

}

蓝图文件由名为Blueprint的工具处理,该工具生成.ninja文件,其中包含编译 Android 软件组件的所有规则。然后.ninja文件由名为Ninja的工具处理,该工具将编译所有软件组件并生成 Android 图像(稍后将详细介绍图像)。

在撰写本文时,并非所有 makefile ( Android.mk ) 都转换为蓝图文件 ( Android.bp )。为此,有一个名为kati的工具,负责将Android.mk文件转换为.ninja文件。随着时间的推移,所有Android.mk文件应该会逐渐转换为Android.bp,不再需要在 Android 构建系统中使用 kati 工具。

下图是Android构建过程的总结: 构建Android非常简单。您可以使用三个简单的命令来完成此操作:一个用于获取初始化环境的脚本,第二个用于选择目标设备 ( product-variant ),最后一个用于开始构建。以下命令将为模拟器构建 Android:

$ source build/envsetup.sh

$ lunch aosp_x86_64-eng

$ make

几个小时后,我们在out/target/product/ 中得到了图像:

$ cd out/target/product/generic_x86_64/ && ls *.img

cache.img super_empty.img vbmeta.img

dtb.img super.img vendor_boot-debug.img

encryptionkey.img system.img vendor_boot.img

ramdisk-debug.img system-qemu.img vendor.img

ramdisk.img userdata.img vendor-qemu.img

ramdisk-qemu.img userdata-qemu.img

现在,所有这些图像是什么?Android 中的 rootfs 是如何组织的?

rootfs 组织和分区布局

Linux 系统上的 rootfs 组织(大部分)是标准化的,基本上由两个标准定义:Filesystem Hierarchy Standard和Linux Standard Base。

Linux 发行版试图符合这些标准,使应用程序易于移植,并在用户和开发人员需要使用不同的 Linux 系统时简化他们的生活。

但正如您所料,Android 是个例外!

这是 Android 系统(Android 11,为 QEMU 构建)的根分区列表。请问/sbin、/usr、/lib等Linux系统常用目录在哪里?

# ls /

acct d etc mnt sdcard

apex data init odm storage

bin data_mirror init.environ.rc oem sys

bugreports debug_ramdisk linkerconfig proc system

cache default.prop lost+found product system_ext

config dev metadata res vendor

他们不在!在Android中,操作系统组件(应用程序、库)位于/system目录(系统分区的挂载点),用户数据/配置(包括运行时安装的应用程序)位于/data目录(系统分区的挂载点)。数据分区)。还有许多其他分区,如缓存(下载的文件和临时数据)、供应商(来自 SoC 制造商的特定文件)和 odm(来自设备制造商的特定文件)。

这是 Android 11 上分区布局的基本概述(可能因制造商/设备而异):

与典型的嵌入式 Linux 系统非常不同,对吧?

那么现在,我们为什么不讨论一下文件系统的内容呢?因为它们也有很大的不同。让我们从 C 库开始。

安卓 C 库

基于 Linux 内核的操作系统的主要组件之一是 C 库。

C 库实现了操作系统的 API,为应用程序提供了通过系统调用访问内核服务的接口。

有几个 C 库可用于 Linux 系统,包括 glibc、uclibc-ng 和 musl。但是 Android 有自己的 C 库:Bionic!

我可以想象至少有三个原因可能促使 Google 实现自己的 C 库:许可、速度和大小。实现非常简单,轻量级,并在 BSD 许可下发布。

需要提及的一件重要事情是它没有完整的 POSIX 支持,这使得为 Android 构建本机 Linux 应用程序变得更加困难。

例如,请参阅下面来自BusyBox 中 libbb/missing_syscalls.c的代码片段。该定义的(机器人)#如果因为一些仿生功能不遵循POSIX标准是必需的。

#if defined(ANDROID) || defined(__ANDROID__)

/*# include - for struct timex, but may collide with */

# include

pid_t getsid(pid_t pid)

{

return syscall(__NR_getsid, pid);

}

int sethostname(const char *name, size_t len)

{

return syscall(__NR_sethostname, name, len);

}

struct timex;

int adjtimex(struct timex *buf)

{

return syscall(__NR_adjtimex, buf);

}

int pivot_root(const char *new_root, const char *put_old)

{

return syscall(__NR_pivot_root, new_root, put_old);

}

说到 BusyBox……

为什么 Android 不使用 BusyBox?

在嵌入式 Linux 设备上使用 BusyBox 是很常见的。

Busybox 提供(重新)实现常用工具和应用程序,例如初始化程序、shell 和一些用于操作和配置系统的实用程序。

但是默认情况下,Android 不附带 BusyBox!

Android 使用另外两个(概念上相似的)实现,称为Toolbox和Toybox,它们都是在 BSD 许可下发布的。Toolbox 是 Google 实现的工具,Toybox 是社区实现的工具(由 Rob Landley 发起,BusyBox ex-maintainer)。

并且因为这些工具有一些限制,所以在 Android 设备上安装 BusyBox 是很常见的,尤其是在开发过程中。一个动机是在命令行中有一个好的文本编辑器 ( vi ) 可用。

现在,基于 Linux 的操作系统的一个重要部分是 init 系统。初始化在 Android 中是如何工作的?

安卓初始化系统

简而言之,init 应用程序在挂载 rootfs 后立即由内核执行,负责系统初始化和管理。

Linux 系统的 init 进程有多种实现方式,包括 sysvinit、systemd 和 upstart。正如您可能已经预料到的,Android 有自己的初始化系统!

Android init 进程有 3 个主要职责:

初始化和配置操作系统执行环境(导出环境变量、创建和设置文件和目录的权限、创建链接、挂载文件系统、设置 selinux 等)。启动和监视守护进程。管理系统属性。

init 进程的行为定义在一个配置文件中(默认为/etc/init/hw/init.rc),它与我们习惯的任何 init 配置文件都有很大的不同。以下是来自默认 Android init.rc文件的片段:

import /init.environ.rc

import /system/etc/init/hw/init.usb.rc

import /init.${ro.hardware}.rc

import /vendor/etc/init/hw/init.${ro.hardware}.rc

import /system/etc/init/hw/init.usb.configfs.rc

import /system/etc/init/hw/init.${ro.zygote}.rc

# Cgroups are mounted right before early-init using list from /etc/cgroups.json

on early-init

# Disable sysrq from keyboard

write /proc/sys/kernel/sysrq 0

# Android doesn't need kernel module autoloading, and it causes SELinux

# denials. So disable it by setting modprobe to the empty string. Note: to

# explicitly set a sysctl to an empty string, a trailing newline is needed.

write /proc/sys/kernel/modprobe \n

...

on init

sysclktz 0

# Mix device-specific information into the entropy pool

copy /proc/cmdline /dev/urandom

copy /system/etc/prop.default /dev/urandom

symlink /proc/self/fd/0 /dev/stdin

symlink /proc/self/fd/1 /dev/stdout

symlink /proc/self/fd/2 /dev/stderr

...

# Mount filesystems and start core system services.

on late-init

trigger early-fs

# Mount fstab in init.{$device}.rc by mount_all command. Optional parameter

# '--early' can be specified to skip entries with 'latemount'.

# /system and /vendor must be mounted by the end of the fs stage,

# while /data is optional.

trigger fs

on property:ro.debuggable=1

# Give writes to anyone for the trace folder on debug builds.

# The folder is used to store method traces.

chmod 0773 /data/misc/trace

# Give reads to anyone for the window trace folder on debug builds.

chmod 0775 /data/misc/wmtrace

service ueventd /system/bin/ueventd

class core

critical

seclabel u:r:ueventd:s0

shutdown critical

service console /system/bin/sh

class core

console

disabled

user shell

group shell log readproc

seclabel u:r:shell:s0

setenv HOSTNAME console

...

它确实非常不同。您有动作声明(例如在 init 上)和服务声明(例如服务控制台 /system/bin/sh)。当一个动作在启动时被触发时,假设是early-init,在该触发器中声明的命令将被执行。

这里有很多细节,但我们在这篇文章中没有太多空间来讨论它(我们实际上可以写一篇完整的文章)。现在,让我们关注这个难题的一个重要部分,守护进程!

安卓守护进程

守护进程是在后台运行并负责管理某些系统功能的进程。它们中的大多数在启动时由 init 进程执行,并且通常只要系统正常运行,它们就会在后台运行。

守护进程通常用于控制和集中访问系统资源,在 Android 上,许多守护进程是 Android 框架(Java 代码)和系统资源(网络、存储、能源、无线电、日志记录等)之间的接口。一些例子:

ueventd:负责管理硬件设备的连接(设备热插拔)。它相当于 GNU/Linux 系统上的 udev 或 mdev。vold:(卷守护进程)负责监控来自存储设备的事件。rild:(无线电接口层守护进程)管理与调制解调器芯片的通信(语音和数据)。netd:(网络管理服务守护进程)负责管理网络连接(蓝牙、Wi-Fi、USB 等)。它相当于 GNU/Linux 系统上的 NetworkManager 或 connman。installd:(安装守护进程)负责管理 Android 应用程序(* .apk)及其相关资源的安装。lmkd:(低内存杀手守护进程)负责管理内核低内存杀手接口。

这是在 Android 11 上运行的守护进程的(大部分)完整列表:

# ps -A

USER PID PPID VSZ RSS WCHAN ADDR S NAME

root 1 0 10782796 9696 do_epoll_+ 0 S init

root 122 1 10761204 7376 do_sys_po+ 0 S ueventd

logd 145 1 10764228 7932 __x64_sys+ 0 S logd

lmkd 146 1 10756496 2456 do_epoll_+ 0 S lmkd

system 147 1 10759476 5016 do_epoll_+ 0 S servicemanager

system 148 1 10761244 6488 do_epoll_+ 0 S hwservicemanager

system 149 1 10759572 4028 do_epoll_+ 0 S vndservicemanager

root 153 1 10770096 8732 binder_th+ 0 S vold

tombstoned 250 1 10755388 2128 do_epoll_+ 0 S tombstoned

statsd 266 1 10766140 4572 do_epoll_+ 0 S statsd

root 267 1 10781776 9532 binder_th+ 0 S netd

credstore 306 1 10764440 7296 binder_th+ 0 S credstore

gpu_service 307 1 10762672 6804 binder_th+ 0 S gpuservice

system 308 1 10873496 31972 do_epoll_+ 0 S surfaceflinger

root 316 1 10756876 2656 do_sys_po+ 0 S netmgr

root 318 1 10758880 3072 do_sys_po+ 0 S wifi_forwarder

wifi 320 1 10759960 5464 do_select 0 S hostapd_nohidl

logd 326 1 10756544 3160 __skb_wai+ 0 S logcat

root 352 1 10773084 6376 0 0 S adbd

nobody 354 1 10757496 3164 do_sys_po+ 0 S traced_probes

nobody 355 1 10757632 3464 do_sys_po+ 0 S traced

cameraserver 356 1 58984 17240 binder_th+ 0 S cameraserver

drm 357 1 25952 6512 binder_th+ 0 S drmserver

incidentd 359 1 10761968 4992 do_epoll_+ 0 S incidentd

root 360 1 10765704 6452 binder_th+ 0 S installd

iorapd 361 1 10775424 9536 futex_wai+ 0 S iorapd

keystore 362 1 10764916 7404 binder_th+ 0 S keystore

root 366 1 10765596 5648 binder_th+ 0 S storaged

...

你有没有意识到几乎所有的守护进程都是 Android 特有的?是的,他们确实是。Android 是一个操作系统,几乎所有的用户空间组件都是从头开始构建的!

特别值得一提的是日志记录在 Android 上的工作原理,因为它不使用像 journald 或 rsyslog 这样的常见日志记录 Linux 守护进程。所以现在让我们来谈谈这个。

安卓日志系统

在 Android 中,日志守护进程 ( logd ) 负责管理所有操作系统日志,从应用程序到框架和本机应用程序。

对日志的访问是通过/dev/socket/ 中导出的套接字完成的:

# ls /dev/socket/logd*

/dev/socket/logd /dev/socket/logdr /dev/socket/logdw

要读取或写入日志,无需直接访问这些套接字。为此,应用程序可以使用liblog库。而在终端中,用户可以使用log命令写入日志,并使用logcat工具读取日志:

# logcat

...

10-14 13:36:51.722 771 934 D SmsNumberUtils: enter filterDestAddr. destAddr="[BajqU4K5_YhSYbs-7QUn0dOwcmI]"

10-14 13:36:51.723 771 934 D SmsNumberUtils: destAddr is not formatted.

10-14 13:36:51.723 771 934 D SmsNumberUtils: leave filterDestAddr, new destAddr="[BajqU4K5_YhSYbs-7QUn0dOwcmI]"

10-14 13:36:57.054 316 316 E netmgr : qemu_pipe_open_ns:62: Could not connect to the 'pipe:qemud:network' service:

10-14 13:36:57.054 316 316 E netmgr : Failed to open QEMU pipe 'qemud:network': Invalid argument

10-14 13:36:57.324 318 318 E wifi_forwarder: qemu_pipe_open_ns:62: Could not connect to the 'pipe:qemud:wififorward' service:

10-14 13:36:57.325 318 318 E wifi_forwarder: RemoteConnection failed to initialize: RemoteConnection failed to open pipe

...

10-14 14:37:45.408 494 1324 D WifiNl80211Manager: Scan result ready event

10-14 14:37:45.408 494 1324 D WifiNative: Scan result ready event

10-14 14:37:59.109 316 316 E netmgr : qemu_pipe_open_ns:62: Could not connect to the 'pipe:qemud:network' service:

10-14 14:37:59.109 316 316 E netmgr : Failed to open QEMU pipe 'qemud:network': Invalid argument

10-14 14:37:59.574 318 318 E wifi_forwarder: qemu_pipe_open_ns:62: Could not connect to the 'pipe:qemud:wififorward' service:

10-14 14:37:59.575 318 318 E wifi_forwarder: RemoteConnection failed to initialize: RemoteConnection failed to open pipe

10-14 14:38:00.003 642 642 D KeyguardClockSwitch: Updating clock: 238

10-14 14:38:59.127 316 316 E netmgr : qemu_pipe_open_ns:62: Could not connect to the 'pipe:qemud:network' service:

10-14 14:38:59.127 316 316 E netmgr : Failed to open QEMU pipe 'qemud:network': Invalid argument

10-14 14:38:59.585 318 318 E wifi_forwarder: qemu_pipe_open_ns:62: Could not connect to the 'pipe:qemud:wififorward' service:

10-14 14:38:59.585 318 318 E wifi_forwarder: RemoteConnection failed to initialize: RemoteConnection failed to open pipe

10-14 14:39:00.003 642 642 D KeyguardClockSwitch: Updating clock: 239

10-14 14:39:59.142 316 316 E netmgr : qemu_pipe_open_ns:62: Could not connect to the 'pipe:qemud:network' service:

10-14 14:39:59.142 316 316 E netmgr : Failed to open QEMU pipe 'qemud:network': Invalid argument

10-14 14:39:59.634 318 318 E wifi_forwarder: qemu_pipe_open_ns:62: Could not connect to the 'pipe:qemud:wififorward' service:

10-14 14:39:59.634 318 318 E wifi_forwarder: RemoteConnection failed to initialize: RemoteConnection failed to open pipe

10-14 14:40:00.006 642 642 D KeyguardClockSwitch: Updating clock: 240

...

经过几年的 Android 工作,我可以说 Android 日志系统相当不错,在平台上开发时非常有用。

谈到开发,在将 Android 移植到嵌入式设备时,编写与硬件对话的代码是该过程的重要组成部分。那么为什么我们现在不讨论硬件访问在 Android 中是如何工作的呢?

硬件访问和 Android HAL

在嵌入式 Linux 系统上,对硬件设备的访问通常通过/dev或/sys 中的条目暴露给应用程序。但是在 Android 上,我们依靠一个称为HAL(硬件抽象层)的附加层来抽象对硬件设备的访问。

主要思想是将系统服务(稍后会详细介绍)与 Linux 内核公开的接口解耦,因此如果内核接口发生变化,您只需更换 HAL,系统服务将继续工作。大多数 HAL 基本上是作为独立进程运行的服务,该进程公开通过 Binder 使用的接口(以称为HIDL的语言声明)。Android 中大多数支持的硬件设备都有 HAL 定义和实现,如显示器、相机、音频、传感器等。

但是要完全理解上图,就得说说Android框架和系统服务。

Android 框架和系统服务

因此,Android 框架是所有 Java(以及现在的 Kotlin)代码所在的地方。我们在那里有向应用程序公开的系统服务和 API。

尤其是系统服务,是Android操作系统中非常重要的一部分。它们基本上是公开接口(通过 Binder)以供其他系统服务和应用程序(通过 API)使用的对象。

在 Android 终端上,您可以使用以下命令列出系统服务:

# service list

Found 184 services:

0 DockObserver: []

1 SurfaceFlinger: [android.ui.ISurfaceComposer]

2 accessibility: [android.view.accessibility.IAccessibilityManager]

3 account: [android.accounts.IAccountManager]

4 activity: [android.app.IActivityManager]

5 activity_task: [android.app.IActivityTaskManager]

6 adb: [android.debug.IAdbManager]

7 alarm: [android.app.IAlarmManager]

8 android.hardware.identity.IIdentityCredentialStore/default: [android.hardware.identity.IIdentityCredentialStore]

9 android.hardware.light.ILights/default: [android.hardware.light.ILights]

10 android.hardware.power.IPower/default: [android.hardware.power.IPower]

11 android.hardware.rebootescrow.IRebootEscrow/default: [android.hardware.rebootescrow.IRebootEscrow]

12 android.hardware.vibrator.IVibrator/default: [android.hardware.vibrator.IVibrator]

13 android.security.identity: [android.security.identity.ICredentialStoreFactory]

14 android.security.keystore: [android.security.keystore.IKeystoreService]

15 android.service.gatekeeper.IGateKeeperService: [android.service.gatekeeper.IGateKeeperService]

16 app_binding: []

17 app_integrity: [android.content.integrity.IAppIntegrityManager]

18 appops: [com.android.internal.app.IAppOpsService]

19 appwidget: [com.android.internal.appwidget.IAppWidgetService]

20 audio: [android.media.IAudioService]

21 auth: [android.hardware.biometrics.IAuthService]

...

假设您正在编写一个 Android 应用程序来读取传感器。这是将要发生的事情:

应用程序将从 Android API (SensorManager) 调用方法以从传感器请求数据。API (SensorManager) 将向系统服务(在本例中为 SensorService)发送消息(通过 Binder)。系统服务负责管理对其控制的资源的访问。在此示例中,SensorService 管理对传感器的访问。它会做的第一件事是检查权限:应用程序是否有权访问传感器?如果没有,它将向应用程序返回一个异常。如果访问被授予,它会通过 Binder 向 HAL(传感器 HAL)发送消息以请求来自传感器的数据。传感器 HAL 将读取传感器,可能通过内核 IIO 驱动程序公开的文件,并将数据返回到系统服务 (SensorService)。系统服务(SensorService)将传感器数据返回给应用程序。

这是另一个解释这些组件如何相互通信的图表:

现在您看到 Android 与典型 Linux 系统的真正区别了吗?

我们仍然需要谈论应用程序…

安卓应用

在嵌入式设备上使用 Android 的优势之一是定义明确的 API 集,这大大简化了开发并显着提高了生产力。

在 Android 中,应用程序是使用 Google SDK 用 Ja​​va 或 Kotlin 编写的,并打包在扩展名为.apk 的文件中,其中包含应用程序使用的编译代码、数据和资源。

Android 应用程序基本上由 4 类组件组成:活动、服务、广播接收器和内容提供器。一个应用程序可以包含一个或多个组件,一件好事是组件可以被重用并通过一种称为意图的机制相互通信。

最后,即使我们想使用Android但不关心操作系统内部架构,我们仍然需要学习Android范式,这与通常的Linux应用程序开发有很大不同,比如说在Qt或GTK。

让我们现在结束?

Android 是不是 Linux 发行版?

我们可以在这篇文章中看到,Android 确实与典型的 GNU/Linux 系统不同,从我们管理源代码和构建系统的方式到文件系统的组织和组件,以及所有组件通过 IPC 进行通信的模块化架构/RPC。

我们可以清楚地看到的唯一相似之处是 Linux 内核的用法。在 Android 中,几乎所有其他东西都不同。

那么 Android 是 Linux 发行版吗?

这取决于您如何“分类”Linux 发行版。如果Linux发行版是任何使用Linux内核的系统,那么我们大概可以说Android是Linux发行版。如果 Linux 发行版是一个遵循相同标准并共享一些公共组件的系统,例如 GNU 项目提供的那些,那么 Android 绝对不是 Linux 发行版。

值得一提的是,随着时间的推移,Android 正在不断发展。Google 面临的主要挑战之一是软件更新。他们无法更新任何设备,因为它不在他们的控制之下。

Apple 制造 SoC、设备本身(当然!)和软件,几乎控制着供应链的每个方面。因此,他们可以根据需要(随时)更新现场的所有设备。

现在谷歌没有这个能力。除了 Pixel 设备,他们对三星或小米等其他公司制造的设备没有太多控制权。

但他们想要这种控制。这就是为什么他们创建项目来改善这种情况,例如Project Trebble、Generic System Images和Generic Kernel Image。

我们在本文中看到的许多建筑设计都来自这些项目,而且可能还会有更多。是不是更好,只有用户和市场会告诉你。

相关推荐

十二仙子指的是谁
亚洲365bet备用

十二仙子指的是谁

📅 10-08 👀 5295
Win7系统如何快速搜索文件夹内文件?3种高效方法详解
beat365亚洲体育在线

Win7系统如何快速搜索文件夹内文件?3种高效方法详解

📅 09-19 👀 7974
熹妃传皇子怎么培养 皇子培养方法详解
亚洲365bet备用

熹妃传皇子怎么培养 皇子培养方法详解

📅 07-25 👀 2605
dnf90狂战士/狱血魔神/帝血弑天远古传说套选择
365bet官方网址

dnf90狂战士/狱血魔神/帝血弑天远古传说套选择

📅 09-30 👀 2817
世界杯有多少支球队_为什么世界杯是32支球队参赛
beat365亚洲体育在线

世界杯有多少支球队_为什么世界杯是32支球队参赛

📅 06-29 👀 9148
逆水寒开服如何排队
beat365亚洲体育在线

逆水寒开服如何排队

📅 10-20 👀 6404
世界杯有史以来最伟大的10位巨星,贝利 马拉多纳 罗纳尔多领衔
分页组件文档
亚洲365bet备用

分页组件文档

📅 10-19 👀 1440
软硬大比拼 硅胶、TPU和PC材质对比
亚洲365bet备用

软硬大比拼 硅胶、TPU和PC材质对比

📅 08-02 👀 5440