Android 与其他基于 Linux 的系统有何不同?
文章目錄
- 概述
- Linux Kernel
- AOSP
- 安卓構建系統(tǒng)
- rootfs 組織和分區(qū)布局
- 安卓 C 庫
- 為什么 Android 不使用 BusyBox?
- 安卓初始化系統(tǒng)
- 安卓守護進程
- 安卓日志系統(tǒng)
- 硬件訪問和 Android HAL
- Android 框架和系統(tǒng)服務
- 安卓應用
- Android 是不是 Linux 發(fā)行版?
原文:https://embeddedbits.org/what-differs-android-from-other-linux-based-systems/
?如果您是嵌入式 Linux 開發(fā)人員但從未使用過嵌入式 Android,那么本文適合您。如果您開發(fā)或維護 Linux 發(fā)行版,并且我想開始開發(fā) Android 發(fā)行版,那么本文適合您。如果您是一名 Android 應用程序開發(fā)人員并想了解一些 Android(內(nèi)部)的工作原理,本文也適合您。如果你只是好奇,這篇文章也適合你!😃
?我們將從構建系統(tǒng)到分區(qū)布局,從 rootfs 的內(nèi)容到操作系統(tǒng)組件的架構,從 IPC/RPC 機制到硬件訪問如何工作的不同角度來比較 GNU/Linux 系統(tǒng)和 Android。
概述
?如果您查看任何嵌入式 Linux 系統(tǒng)的架構,您總會發(fā)現(xiàn)相同的主要組件:
?如果現(xiàn)在您查看基于 Android 的系統(tǒng)的相同圖表,會有什么區(qū)別?
從上圖我們可以看出,Android 用戶空間組件清楚地分為三個主要層:
在詳細研究 Android 用戶空間組件之前,讓我們先談談內(nèi)核。
Linux Kernel
?要運行基于 Android 的系統(tǒng),我們需要在 Linux 內(nèi)核中啟用一些額外的“功能”。如果我嘗試討論大多數(shù)功能,這篇文章會太長,但我可以評論一些:
- Binder:這是Android中使用的IPC(Inter-Process Communication)和RPC(Remote Procedure Call)機制。您可以與 DBUS 做一個粗略的比較,但 DBUS 在用戶空間中運行,而 Binder 是一種更快、更輕的基于內(nèi)核的實現(xiàn)。
- Ashmem:Android 中的默認共享內(nèi)存分配器(Google 不喜歡 POSIX SHM)。
- 低內(nèi)存殺手:建立在內(nèi)核OOM(內(nèi)存不足)殺手之上的邏輯,與守護進程(lmkd)結合,有助于在低內(nèi)存情況下管理系統(tǒng)。
大多數(shù)這些特性已經(jīng)在主線內(nèi)核中可用,但如果你想要“Androidisms”的完整列表,你可以克隆谷歌的內(nèi)核通用存儲庫并搜索以“ANDROID:”開頭的提交:
?盡管 Linux 內(nèi)核中有這些(以及其他一些)主要變化,Android 在用戶空間組件及其架構(所謂的 Android 平臺)方面確實與 GNU/Linux 系統(tǒng)不同,Android 平臺的源代碼是在名為AOSP(Android 開源項目)的項目中提供。
AOSP
AOSP 由數(shù)百個存儲庫(特別是 Android 11 中的 780 個)組成,您可以在https://android.googlesource.com/ 中查看所有這些存儲庫。
?源代碼是用已知的工具管理的,比如repo和git,它是巨大的!Android 11 是 100GB 的源代碼加上一次構建后的 115GB。因此,您確實需要大量磁盤空間來處理 Android 源代碼。
克隆最新的 AOSP 源代碼就像運行以下兩個命令一樣簡單(可以在repo init 中使用-b來克隆特定的Android 發(fā)布標記或分支):
$ 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作為一個開源項目,有多個討論組與社區(qū)和開發(fā)者進行交流,任何人都可以通過Gerrit 代碼審查工具為項目做出貢獻。
絕大多數(shù)軟件組件在 Apache 和 BSD 許可下,一些軟件組件在 GPL/LGPL 許可下,一些谷歌應用程序是閉源的(例如谷歌播放、Gmail、谷歌地圖、YouTube 等)。這些應用程序在名為Google 移動服務(GMS)的軟件包中提供,要獲取它們,您需要通過Android 兼容性計劃(ACP)對設備進行認證。
當我們下載 AOSP 源代碼時,與其他嵌入式 Linux 開發(fā)方法相比,我們可以看到一些差異。
與現(xiàn)成的發(fā)行版(例如 Debian)不同,您可以輕松下載完整的源代碼并從頭開始構建發(fā)行版(例如,如果您想創(chuàng)建一個自定義的 Debian 系統(tǒng),您通常從預編譯的包中完成) )。
與構建系統(tǒng)方法(例如 Buildroot、OpenEmbedded)相比,在 Android 中,我們似乎有一個使用repo sync命令下載的“大應用程序” 。當然這不是真的。我們在那里有數(shù)以千計的項目和存儲庫,它們最終將組成操作系統(tǒng)映像。而將所有內(nèi)容放在一起的責任在于 Android 構建系統(tǒng)…
安卓構建系統(tǒng)
?在以前的 Android 版本中,構建系統(tǒng)完全基于 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 = optionalinclude $(BUILD_EXECUTABLE)?基于 Makefile 的構建系統(tǒng)有幾個缺點,包括增量構建的性能低下,并且在最新版本的 Android 中被Soong 構建系統(tǒng)取代。
?在 Soong 構建系統(tǒng)中,編譯軟件組件的規(guī)則在 Blueprint 文件 ( Android.bp )中定義,其語法類似于 JSON。以下是在 Android 中構建“Hello World”C 應用程序的相同示例,但使用的是藍圖文件:
cc_binary {name: "helloworld",srcs: ["helloworld.c"],tags: ["optional"], }?藍圖文件由名為Blueprint的工具處理,該工具生成.ninja文件,其中包含編譯 Android 軟件組件的所有規(guī)則。然后.ninja文件由名為Ninja的工具處理,該工具將編譯所有軟件組件并生成 Android 圖像(稍后將詳細介紹圖像)。
?在撰寫本文時,并非所有 makefile ( Android.mk ) 都轉(zhuǎn)換為藍圖文件 ( Android.bp )。為此,有一個名為kati的工具,負責將Android.mk文件轉(zhuǎn)換為.ninja文件。隨著時間的推移,所有Android.mk文件應該會逐漸轉(zhuǎn)換為Android.bp,不再需要在 Android 構建系統(tǒng)中使用 kati 工具。
下圖是Android構建過程的總結:
?構建Android非常簡單。您可以使用三個簡單的命令來完成此操作:一個用于獲取初始化環(huán)境的腳本,第二個用于選擇目標設備 ( product-variant ),最后一個用于開始構建。以下命令將為模擬器構建 Android:
幾個小時后,我們在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現(xiàn)在,所有這些圖像是什么?Android 中的 rootfs 是如何組織的?
rootfs 組織和分區(qū)布局
Linux 系統(tǒng)上的 rootfs 組織(大部分)是標準化的,基本上由兩個標準定義:Filesystem Hierarchy Standard和Linux Standard Base。
Linux 發(fā)行版試圖符合這些標準,使應用程序易于移植,并在用戶和開發(fā)人員需要使用不同的 Linux 系統(tǒng)時簡化他們的生活。
但正如您所料,Android 是個例外!
這是 Android 系統(tǒng)(Android 11,為 QEMU 構建)的根分區(qū)列表。請問/sbin、/usr、/lib等Linux系統(tǒng)常用目錄在哪里?
# 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中,操作系統(tǒng)組件(應用程序、庫)位于/system目錄(系統(tǒng)分區(qū)的掛載點),用戶數(shù)據(jù)/配置(包括運行時安裝的應用程序)位于/data目錄(系統(tǒng)分區(qū)的掛載點)。數(shù)據(jù)分區(qū))。還有許多其他分區(qū),如緩存(下載的文件和臨時數(shù)據(jù))、供應商(來自 SoC 制造商的特定文件)和 odm(來自設備制造商的特定文件)。
這是 Android 11 上分區(qū)布局的基本概述(可能因制造商/設備而異):
與典型的嵌入式 Linux 系統(tǒng)非常不同,對吧?
那么現(xiàn)在,我們?yōu)槭裁床挥懻撘幌挛募到y(tǒng)的內(nèi)容呢?因為它們也有很大的不同。讓我們從 C 庫開始。
安卓 C 庫
基于 Linux 內(nèi)核的操作系統(tǒng)的主要組件之一是 C 庫。
C 庫實現(xiàn)了操作系統(tǒng)的 API,為應用程序提供了通過系統(tǒng)調(diào)用訪問內(nèi)核服務的接口。
有幾個 C 庫可用于 Linux 系統(tǒng),包括 glibc、uclibc-ng 和 musl。但是 Android 有自己的 C 庫:Bionic!
我可以想象至少有三個原因可能促使 Google 實現(xiàn)自己的 C 庫:許可、速度和大小。實現(xiàn)非常簡單,輕量級,并在 BSD 許可下發(fā)布。
需要提及的一件重要事情是它沒有完整的 POSIX 支持,這使得為 Android 構建本機 Linux 應用程序變得更加困難。
例如,請參閱下面來自BusyBox 中 libbb/missing_syscalls.c的代碼片段。該定義的(機器人)#如果因為一些仿生功能不遵循POSIX標準是必需的。
#if defined(ANDROID) || defined(__ANDROID__) /*# include <linux/timex.h> - for struct timex, but may collide with <time.h> */ # include <sys/syscall.h> 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 提供(重新)實現(xiàn)常用工具和應用程序,例如初始化程序、shell 和一些用于操作和配置系統(tǒng)的實用程序。
但是默認情況下,Android 不附帶 BusyBox!
Android 使用另外兩個(概念上相似的)實現(xiàn),稱為Toolbox和Toybox,它們都是在 BSD 許可下發(fā)布的。Toolbox 是 Google 實現(xiàn)的工具,Toybox 是社區(qū)實現(xiàn)的工具(由 Rob Landley 發(fā)起,BusyBox ex-maintainer)。
并且因為這些工具有一些限制,所以在 Android 設備上安裝 BusyBox 是很常見的,尤其是在開發(fā)過程中。一個動機是在命令行中有一個好的文本編輯器 ( vi ) 可用。
現(xiàn)在,基于 Linux 的操作系統(tǒng)的一個重要部分是 init 系統(tǒng)。初始化在 Android 中是如何工作的?
安卓初始化系統(tǒng)
簡而言之,init 應用程序在掛載 rootfs 后立即由內(nèi)核執(zhí)行,負責系統(tǒng)初始化和管理。
Linux 系統(tǒng)的 init 進程有多種實現(xiàn)方式,包括 sysvinit、systemd 和 upstart。正如您可能已經(jīng)預料到的,Android 有自己的初始化系統(tǒng)!
Android init 進程有 3 個主要職責:
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 keyboardwrite /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 initsysclktz 0# Mix device-specific information into the entropy poolcopy /proc/cmdline /dev/urandomcopy /system/etc/prop.default /dev/urandomsymlink /proc/self/fd/0 /dev/stdinsymlink /proc/self/fd/1 /dev/stdoutsymlink /proc/self/fd/2 /dev/stderr...# Mount filesystems and start core system services. on late-inittrigger 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 fson 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/wmtraceservice ueventd /system/bin/ueventdclass corecriticalseclabel u:r:ueventd:s0shutdown criticalservice console /system/bin/shclass coreconsoledisableduser shellgroup shell log readprocseclabel u:r:shell:s0setenv HOSTNAME console...它確實非常不同。您有動作聲明(例如在 init 上)和服務聲明(例如服務控制臺 /system/bin/sh)。當一個動作在啟動時被觸發(fā)時,假設是early-init,在該觸發(fā)器中聲明的命令將被執(zhí)行。
這里有很多細節(jié),但我們在這篇文章中沒有太多空間來討論它(我們實際上可以寫一篇完整的文章)?,F(xiàn)在,讓我們關注這個難題的一個重要部分,守護進程!
安卓守護進程
守護進程是在后臺運行并負責管理某些系統(tǒng)功能的進程。它們中的大多數(shù)在啟動時由 init 進程執(zhí)行,并且通常只要系統(tǒng)正常運行,它們就會在后臺運行。
守護進程通常用于控制和集中訪問系統(tǒng)資源,在 Android 上,許多守護進程是 Android 框架(Java 代碼)和系統(tǒng)資源(網(wǎng)絡、存儲、能源、無線電、日志記錄等)之間的接口。一些例子:
- ueventd:負責管理硬件設備的連接(設備熱插拔)。它相當于 GNU/Linux 系統(tǒng)上的 udev 或 mdev。
- vold:(卷守護進程)負責監(jiān)控來自存儲設備的事件。
- rild:(無線電接口層守護進程)管理與調(diào)制解調(diào)器芯片的通信(語音和數(shù)據(jù))。
- netd:(網(wǎng)絡管理服務守護進程)負責管理網(wǎng)絡連接(藍牙、Wi-Fi、USB 等)。它相當于 GNU/Linux 系統(tǒng)上的 NetworkManager 或 connman。
- installd:(安裝守護進程)負責管理 Android 應用程序(* .apk)及其相關資源的安裝。
- lmkd:(低內(nèi)存殺手守護進程)負責管理內(nèi)核低內(nèi)存殺手接口。
這是在 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 是一個操作系統(tǒng),幾乎所有的用戶空間組件都是從頭開始構建的!
特別值得一提的是日志記錄在 Android 上的工作原理,因為它不使用像 journald 或 rsyslog 這樣的常見日志記錄 Linux 守護進程。所以現(xiàn)在讓我們來談談這個。
安卓日志系統(tǒng)
在 Android 中,日志守護進程 ( logd ) 負責管理所有操作系統(tǒng)日志,從應用程序到框架和本機應用程序。
對日志的訪問是通過/dev/socket/ 中導出的套接字完成的:
# ls /dev/socket/logd* /dev/socket/logd /dev/socket/logdr /dev/socket/logdw要讀取或?qū)懭肴罩?#xff0c;無需直接訪問這些套接字。為此,應用程序可以使用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 ...經(jīng)過幾年的 Android 工作,我可以說 Android 日志系統(tǒng)相當不錯,在平臺上開發(fā)時非常有用。
談到開發(fā),在將 Android 移植到嵌入式設備時,編寫與硬件對話的代碼是該過程的重要組成部分。那么為什么我們現(xiàn)在不討論硬件訪問在 Android 中是如何工作的呢?
硬件訪問和 Android HAL
在嵌入式 Linux 系統(tǒng)上,對硬件設備的訪問通常通過/dev或/sys 中的條目暴露給應用程序。但是在 Android 上,我們依靠一個稱為HAL(硬件抽象層)的附加層來抽象對硬件設備的訪問。
主要思想是將系統(tǒng)服務(稍后會詳細介紹)與 Linux 內(nèi)核公開的接口解耦,因此如果內(nèi)核接口發(fā)生變化,您只需更換 HAL,系統(tǒng)服務將繼續(xù)工作。大多數(shù) HAL 基本上是作為獨立進程運行的服務,該進程公開通過 Binder 使用的接口(以稱為HIDL的語言聲明)。Android 中大多數(shù)支持的硬件設備都有 HAL 定義和實現(xiàn),如顯示器、相機、音頻、傳感器等。
但是要完全理解上圖,就得說說Android框架和系統(tǒng)服務。
Android 框架和系統(tǒng)服務
因此,Android 框架是所有 Java(以及現(xiàn)在的 Kotlin)代碼所在的地方。我們在那里有向應用程序公開的系統(tǒng)服務和 API。
尤其是系統(tǒng)服務,是Android操作系統(tǒng)中非常重要的一部分。它們基本上是公開接口(通過 Binder)以供其他系統(tǒng)服務和應用程序(通過 API)使用的對象。
在 Android 終端上,您可以使用以下命令列出系統(tǒng)服務:
# 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 應用程序來讀取傳感器。這是將要發(fā)生的事情:
這是另一個解釋這些組件如何相互通信的圖表:
現(xiàn)在您看到 Android 與典型 Linux 系統(tǒng)的真正區(qū)別了嗎?
我們?nèi)匀恍枰務搼贸绦颉?/p>
安卓應用
在嵌入式設備上使用 Android 的優(yōu)勢之一是定義明確的 API 集,這大大簡化了開發(fā)并顯著提高了生產(chǎn)力。
在 Android 中,應用程序是使用 Google SDK 用 Ja??va 或 Kotlin 編寫的,并打包在擴展名為.apk 的文件中,其中包含應用程序使用的編譯代碼、數(shù)據(jù)和資源。
Android 應用程序基本上由 4 類組件組成:活動、服務、廣播接收器和內(nèi)容提供器。一個應用程序可以包含一個或多個組件,一件好事是組件可以被重用并通過一種稱為意圖的機制相互通信。
最后,即使我們想使用Android但不關心操作系統(tǒng)內(nèi)部架構,我們?nèi)匀恍枰獙W習Android范式,這與通常的Linux應用程序開發(fā)有很大不同,比如說在Qt或GTK。
讓我們現(xiàn)在結束?
Android 是不是 Linux 發(fā)行版?
我們可以在這篇文章中看到,Android 確實與典型的 GNU/Linux 系統(tǒng)不同,從我們管理源代碼和構建系統(tǒng)的方式到文件系統(tǒng)的組織和組件,以及所有組件通過 IPC 進行通信的模塊化架構/RPC。
我們可以清楚地看到的唯一相似之處是 Linux 內(nèi)核的用法。在 Android 中,幾乎所有其他東西都不同。
那么 Android 是 Linux 發(fā)行版嗎?
這取決于您如何“分類”Linux 發(fā)行版。如果Linux發(fā)行版是任何使用Linux內(nèi)核的系統(tǒng),那么我們大概可以說Android是Linux發(fā)行版。如果 Linux 發(fā)行版是一個遵循相同標準并共享一些公共組件的系統(tǒng),例如 GNU 項目提供的那些,那么 Android 絕對不是 Linux 發(fā)行版。
值得一提的是,隨著時間的推移,Android 正在不斷發(fā)展。Google 面臨的主要挑戰(zhàn)之一是軟件更新。他們無法更新任何設備,因為它不在他們的控制之下。
Apple 制造 SoC、設備本身(當然!)和軟件,幾乎控制著供應鏈的每個方面。因此,他們可以根據(jù)需要(隨時)更新現(xiàn)場的所有設備。
現(xiàn)在谷歌沒有這個能力。除了 Pixel 設備,他們對三星或小米等其他公司制造的設備沒有太多控制權。
但他們想要這種控制。這就是為什么他們創(chuàng)建項目來改善這種情況,例如Project Trebble、Generic System Images和Generic Kernel Image。
我們在本文中看到的許多建筑設計都來自這些項目,而且可能還會有更多。是不是更好,只有用戶和市場會告訴你。
總結
以上是生活随笔為你收集整理的Android 与其他基于 Linux 的系统有何不同?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 蓝桥杯Python初级组测试题之Turt
- 下一篇: linux 其他常用命令