一文搞懂Android和嵌入式Linux开发差异点

前言

因业务需要,过去一年从熟悉的Android开发开始涉及嵌入式Linux开发,编程语言也从Java/Kotlin变成难上手的C++,这里面其实有很多差异点,特此整理本文来详细对比这两者开发的异同,便于对嵌入式Linux开发感兴趣的同学一些参考。

适用人群

  • 有一定Android开发经验
  • 想了解嵌入Linux开发的同学

思维导图

架构对比

image.png

注:左边是Android的平台架构,右边是目前我们Linux的平台架构。

由下往上看:

  • 硬件层:硬件层是操作系统与硬件设备之间的桥梁,它使得操作系统和应用程序能够与各种硬件设备进行通信,从而实现设备的控制和管理。设备类型Android对应的比如智能手机、平板、物联网设备等,Linux对应的比如嵌入式设备、物联网设备等。
  • Linux内核:Linux内核是Linux操作系统的核心组件,它负责管理系统的硬件资源、提供程序运行所需的环境以及协调程序之间的相互作用。比如Linux会负责进程管理、内存管理、文件系统、设备驱动、网络协议栈、系统调用和安全和权限管理等。
  • 系统层:这一层包含了一系列用于实现基本的系统功能和服务的库。比如通过libc或glibc来访问操作系统提供的服务。
  • 应用框架层:这一层就是我们常说的Framework,在Android中提供的是用于开发Android应用程序的API和组件,比如Activity、Service、Broadcast Receiver等。在Linux中也有相应的组件和API,一般情况下是通过DBus这种跨进程通信来调用服务,比如日志服务,网络服务等。
  • 应用层:这一层就是最上层我们能看见的应用层,我们在手机能看到的Android App和在嵌入设备看到的Linux应用程序。我们通常使用Java来开发Android应用程序,使用C/C++来开发Linux应用程序。

基础差异对比

项目Android开发嵌入式Linux开发
基础平台基于Linux内核基于Linux内核
开发语言Java/Kotlin(应用层),C/C++(底层库和JNI接口)C/C++,其他语言(如Python)
开发环境Android Studio,Eclipse等Visual Studio Code,Eclipse,Code::Blocks等,或自定义开发环境
用户界面Android UI框架(如XML布局、Activity等)需自选或开发图形界面库(如LVGL、Qt、GTK+等)
系统组件Activity、Service、Broadcast Receiver等无统一系统组件,根据项目需求自行设计和实现
资源管理严格的资源管理规定(如内存、电源等)无统一资源管理规定,需要根据需求进行优化
应用分发Google Play或其他应用市场通过设备制造商或系统集成商进行部署和升级
设备驱动开发Android HAL层设备驱动开发基于Linux内核的设备驱动开发
系统定制和移植Android系统定制和移植嵌入式Linux系统定制和移植
目标设备主要针对移动设备(如手机、平板等)针对各种嵌入式设备(如路由器、工控设备等)

这个表格展示了Android开发和嵌入式Linux开发的主要异同点。虽然它们在底层都基于Linux内核,但在应用开发、用户界面、系统组件等方面有很大的差异。嵌入式Linux的GUI框架就不像Android那么完善和便捷,比如想要实现嵌入式的用户界面,使用C语言开发的LVGL框架来手写界面代码,UI交互代码会显得冗余
example:

#include "../lv_examples.h"
#if LV_BUILD_EXAMPLES && LV_USE_BTN

static void btn_event_cb(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t * btn = lv_event_get_target(e);
    if(code == LV_EVENT_CLICKED) {
        static uint8_t cnt = 0;
        cnt++;

        /*Get the first child of the button which is the label and change its text*/
        lv_obj_t * label = lv_obj_get_child(btn, 0);
        lv_label_set_text_fmt(label, "Button: %d", cnt);
    }
}

/**
 * Create a button with a label and react on click event.
 */
void lv_example_get_started_1(void)
{
    lv_obj_t * btn = lv_btn_create(lv_scr_act());     /*Add a button the current screen*/
    lv_obj_set_pos(btn, 10, 10);                            /*Set its position*/
    lv_obj_set_size(btn, 120, 50);                          /*Set its size*/
    lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_ALL, NULL);           /*Assign a callback to the button*/

    lv_obj_t * label = lv_label_create(btn);          /*Add a label to the button*/
    lv_label_set_text(label, "Button");                     /*Set the labels text*/
    lv_obj_center(label);
}

#endif

UI效果如下:
image.png

跨进程通信对比

在Android和Linux系统中,跨进程通信(IPC)是一种用于在不同进程之间传递数据和消息的机制。以下是Android和Linux中跨进程通信的对比:

维度Android IPCLinux IPC
Binder提供Binder机制进行跨进程通信不支持Binder机制
Unix套接字支持Unix域套接字支持Unix域套接字
消息队列不直接支持SysV消息队列,可通过JNI使用支持SysV消息队列和POSIX消息队列
共享内存支持匿名共享内存(ashmem)和内存文件映射支持SysV共享内存和POSIX共享内存
信号受限的信号支持,不推荐用于IPC支持信号(signal)进行简单的进程间通信
管道和有名管道支持管道(pipe)和有名管道(FIFO)支持管道(pipe)和有名管道(FIFO)
信号量不直接支持SysV信号量,可通过JNI使用支持SysV信号量和POSIX信号量
D-Bus不直接支持D-Bus,可通过第三方库使用支持D-Bus进行桌面环境和系统服务间的通信

其中Binder机制是Android开发非常重要的知识点,原理图如下所示:
image.png

图片引自:https://zhuanlan.zhihu.com/p/35519585

Binder的优势在于提供一种高性能、稳定性和安全性跨进程通信机制。基于C/S架构,职责明确、架构清晰;通信过程中仅需要进行一次内存拷贝,性能仅次于共享内存;然而它为每个APP进程分配UID,可以通过UID鉴别身份。

D-Bus
D-BUS是一种进程间通信(IPC)机制,一般主要用于基于AF_UNIX套接字的本地进程间通信(local IPC)(当然也可以基于TCP/IP)实现跨主机的通信。原理图如下所示:

image.png

图片引自:https://hustcat.github.io/getting-started-with-dbus/

D-Bus协议是一个端到端的通信协议,核心基础概念参考:
image.png

编程语言对比

参数JavaKotlinC++
历史1995年由James Gosling 在 Sun Microsystems 开发2011年由JetBrains开发1979年由Bjarne Stroustrup 在贝尔实验室开发
编程范式面向对象面向对象和函数式编程面向过程和面向对象
平台依赖平台无关平台无关平台相关
编译与解释编译解释编译解释仅编译
内存管理系统控制系统控制手动控制
可移植性可移植可移植不可移植
指针有限支持不支持强烈支持
参数传递按值传递按值传递按值传递和按引用传递
重载仅方法重载运算符和方法重载运算符和方法重载
线程支持内置线程支持内置线程支持依赖第三方线程库
文档注释支持支持不支持
兼容性不兼容其他语言兼容Java兼容C语言
goto语句不支持不支持支持
多重继承单继承单继承单继承和多继承
结构体与共用体不支持支持数据类支持
虚拟关键字所有非静态方法默认virtual不支持virtual关键字支持virtual关键字
硬件离硬件较远离硬件较远接近硬件
数据与功能需在类中,可有包作用域需在类中,可有包作用域提供全局作用域和命名空间作用域
运行时错误检测系统处理系统处理程序员处理
根层次结构支持单根层次结构支持单根层次结构无根层次结构
输入输出System.in 和 System.out.printlnprintln和readLine()Cin和Cout

C++、Java和Kotlin之间的最大区别在于它们的编程范式、内存管理和平台依赖性。

  1. 编程范式:C++支持面向过程和面向对象编程,而Java和Kotlin主要支持面向对象编程。Kotlin还支持函数式编程。
  2. 内存管理:C++需要程序员手动管理内存分配和释放,而Java和Kotlin使用自动内存管理(垃圾回收机制),这使得Java和Kotlin更易于使用,但可能在某些情况下牺牲了性能。
  3. 平台依赖性:C++是平台相关的,需要针对不同平台进行编译。Java和Kotlin则是平台无关的,可以一次编写并在任何支持Java虚拟机(JVM)的平台上运行。Kotlin还可以编译为JavaScript和本地代码,从而实现更广泛的平台兼容性。

这些区别使得C++更适合底层系统开发、性能关键应用和嵌入式系统,而Java和Kotlin更适合跨平台应用、Web应用和移动应用开发。

开发工具、编译工具对比

项目Android开发嵌入式Linux开发
开发工具Android Studio, Eclipse等Visual Studio Code,Eclipse, Code::Blocks等, 或自定义开发环境
编译工具Gradle (应用层), Android NDK (底层库和JNI接口)Make, CMake, Autotools等
编译器Java编译器 (应用层), GCC (底层库和JNI接口)GCC, Clang等
调试器Android Debug Bridge (ADB), Logcat, DDMS等GDB, KGDB等
版本控制Git, SVN, Mercurial等Git, SVN, Mercurial等
性能分析工具Android Profiler, Traceview, Systrace等Perf, Valgrind, OProfile等
静态代码分析Lint, SonarQube等Lint, cppcheck, Coverity等
模拟器/仿真器Android模拟器, Genymotion等QEMU, VirtualBox等
持续集成/部署Jenkins, CircleCI, GitLab CI等Jenkins, CircleCI, GitLab CI等

Android开发和嵌入式Linux开发使用的开发工具和编译工具有一些核心差异,以下是一些主要差异点:
开发工具:
Android开发:

  • Android Studio:这是Google为Android开发者提供的官方集成开发环境(IDE),内置了代码编辑器、调试器、模拟器等工具,支持Java和Kotlin语言进行Android应用开发。
  • ADB(Android Debug Bridge):这是一个命令行工具,用于在开发机和Android设备之间进行通信,支持安装应用、查看系统日志、调试应用等功能。

嵌入式Linux开发:

  • Eclipse、Visual Studio Code等通用IDE:这些IDE支持C/C++和其他语言,可以用于嵌入式Linux应用开发。
  • GDB(GNU Debugger):这是一个强大的源代码级调试器,用于调试嵌入式Linux应用程序。

编译工具:
Android开发:

  • Gradle:这是Android的官方构建工具,用于编译和打包Android应用。
  • Android NDK(Native Development Kit):这是一个工具集,用于编译和链接使用C/C++编写的Android应用的本地部分。

嵌入式Linux开发:

  • GCC(GNU Compiler Collection):这是一个开源的编译器集合,用于编译C/C++和其他语言的代码。
  • Make:这是一个构建工具,用于自动化编译和链接过程。
  • CMake:这是一个跨平台的构建系统,用于生成Makefile或其他构建脚本。

包管理和依赖管理对比

项目Android开发嵌入式Linux开发
包管理系统APK (Android Package)dpkg, RPM, ipkg等
包管理工具ADB (Android Debug Bridge)apt-get, yum, opkg等
依赖管理Gradle, Maven等Conan,Makefile, autoconf等
应用分发国内应用商店(小米、华为、OPPO、Vivo等)、Google Play, APKPure等通过设备制造商或系统集成商进行部署和升级
应用更新自建应用升级,OTA升级更新,Google Play自动更新OTA升级更新,也可以手动更新或通过脚本自动更新

在Android和嵌入式Linux开发中,包管理和依赖管理是两个相关的概念,它们共同处理应用程序或系统所需的库、组件和资源。以下是它们在包管理和依赖管理方面的主要区别:

Android包管理和依赖管理:

  1. APK(Android Package Kit):这是Android应用程序的安装包格式,包含了应用程序的所有代码、资源、证书以及清单文件等。
  2. 应用商店:Android应用程序通常通过应用商店(如Google Play、华为应用市场等)进行分发和更新。应用商店负责应用程序的审核、签名、安装、更新等功能。
  3. Gradle:Android Studio使用Gradle作为构建系统,它负责处理应用程序的依赖关系。开发者可以在项目的build.gradle文件中声明所需的第三方库,Gradle会自动从远程仓库(如Maven Central、JCenter等)下载并集成这些库。
  4. Android SDK/NDK:Android SDK提供了一套用于开发Android应用程序的API和组件,而Android NDK提供了一套用于处理本地C/C++代码依赖关系的工具。这些组件已经包含在Android系统中,无需额外处理依赖关系。

嵌入式Linux包管理和依赖管理:

  1. 包格式:嵌入式Linux系统的包格式取决于具体的发行版,如Debian/Ubuntu使用deb包,Red Hat/CentOS使用RPM包,OpenWrt使用opkg包等。
  2. 软件仓库:嵌入式Linux应用程序通常通过软件仓库进行分发和更新。软件仓库是一个包含了预编译软件包的服务器,用户可以通过包管理器(如apt、yum、opkg等)从软件仓库安装和更新软件包。
  3. 包管理器:嵌入式Linux发行版通常提供了一个包管理器(如apt、yum、opkg等),用于自动处理系统和应用程序的依赖关系。开发者可以通过包管理器从软件仓库安装所需的库和组件。
  4. 构建系统:嵌入式Linux开发中,Makefile、autoconf和CMake等构建工具可以用于处理项目的依赖关系。开发者需要在构建脚本中手动声明所需的库和组件。

可运行文件对比

Android APK(Android Package)和Linux的可执行文件是两种不同的应用程序格式,它们分别用于Android和Linux系统。以下是Android APK和Linux可执行文件的对比:

维度Android APKLinux可执行文件
文件格式APK(Android Package)ELF(可执行和可链接格式)
用途Android应用程序的安装包Linux系统上的可执行程序
打包内容应用程序代码、资源、清单文件等可执行代码、数据、符号表等
代码类型Java/Kotlin字节码、C/C++库(可选)通常为编译后的机器代码
运行环境Android运行时(ART)或Dalvik虚拟机直接在Linux操作系统上运行
安装过程通过应用商店或ADB安装到Android设备上通过包管理器、编译安装或手动复制到系统目录
更新机制通过应用商店自动更新或手动更新通过包管理器更新或手动替换可执行文件
安全和权限Android权限模型、应用签名Linux用户/组权限、文件权限等

APK文件一览:
image.png

Android Studio 分析apk:
image.png

Linux中ELF可执行文件一览:
image.png

性能分析工具对比

项目Android开发嵌入式Linux开发
CPU性能分析Traceview, Systrace, Simpleperf等Perf, OProfile, GProf等
内存性能分析Android Profiler, LeakCanary等Valgrind, Massif等
磁盘I/O分析Android Profiler, iostat等iostat, blktrace等
网络性能分析Android Profiler, tcpdump等tcpdump, Wireshark, iperf等
电源性能分析Battery Historian, Systrace等PowerTOP, Intel Energy Profiler等
GPU性能分析GPU Debugging, Systrace等GPU PerfStudio, NVIDIA Nsight等
应用性能分析Android Profiler, Firebase Performance等自定义性能分析工具或第三方库
系统性能分析Systrace, Android Profiler等SystemTap, LTTng, Ftrace等
实时性能分析Systrace, Android Profiler等PREEMPT_RT补丁, RT-Tester等

Android我们关注的性能指标在Linux上其实也大同小异,只是在不同的体系下分析手段和工具不一样。相比于Linux分析Android应用的性能要便捷得多,Android Studio内置了强大的性能分析工具—Android Profiler,可以分析CPU、Memory、Network、Energy和Timeline。

写在最后

本文从架构、主要差异、编程语言、IDE/编译工具、包管理、可运行文件和性能分析工具进行了详细对比,如果是有Android开发经验的要迁移到嵌入式Linux需要学习的内容确实还不少,但研发思路是大同小异的,大致就是通过开发框架和编程语言组织代码,通过跨进程通信来实现服务之间的调用,通过编译工具编译成能在系统运行环境的可执行文件,然后你需要关注如何进行应用更新,需要针对跑起来的应用进行性能分析等等。当然实际的研发工作会更加复杂,要实现一个可商用的产品需要结合业务做更多的能力拓展,比如增加日志上报、崩溃捕获、网络组件、存储组件、异步编程组件等等。

### 回答1: Linux内核是一种开源的操作系统内核,是Linux操作系统的核心组成部分。它提供了操作系统与硬件之间的抽象层,负责管理系统的资源、调度任务、提供驱动程序等功能。 Linux内核采用分层的架构,包括硬件抽象层、系统调用层、进程管理层、文件系统层和网络层等。硬件抽象层负责将不同硬件设备的接口统一起来,使得上层的软件可以方便地与硬件进行通信。系统调用层提供了一组API供用户进程调用,如文件操作、网络通信等。进程管理层负责进程的创建、销毁以及调度等任务。文件系统层负责文件的管理和存储。网络层负责网络协议的实现和网络通信。 Linux内核的工作原理可以简单概括为以下几个关键步骤。首先,当一台计算机启动时,BIOS会加载内核映像到内存中,并执行启动代码。然后,内核初始化各种数据结构、驱动程序和关键服务。接下来,内核创建一个初始的用户空间进程,称为init进程。init进程是所有其他进程的祖先进程。在此之后,内核根据调度算法来决定哪个进程可以使用CPU,并依次执行。同时,内核会提供一个中断机制,以便处理硬件事件的优先级。 内核还提供了许多系统调用供用户进程调用,以实现对各种功能的访问。当用户进程需要操作文件、创建进程或进行网络通信时,会通过系统调用将请求传递给内核,由内核代表用户进程执行相应的操作。内核通过调度算法来分配CPU时间片,并通过虚拟内存管理来管理内存资源的分配和回收。 总而言之,Linux内核是一个高度可配置和模块化的操作系统内核,通过分层架构和系统调用机制实现了对硬件的抽象和对用户进程的管理。了解Linux内核的架构和工作原理,有助于深入理解Linux操作系统以及开发和调试相关应用程序。 ### 回答2: Linux是一种开源的操作系统内核,其设计目标是为了在不同的计算机硬件平台上提供高效的、稳定的和安全的操作系统服务。 Linux内核的架构可以分为三个主要部分:进程管理、内存管理和文件系统管理。 在进程管理方面,Linux内核使用了多任务处理技术,可以同时运行多个进程。每个进程都有独立的地址空间和资源,通过调度算法可以合理分配CPU时间片,优化系统的响应速度和资源利用率。 在内存管理方面,Linux内核使用了虚拟内存技术,将物理内存和逻辑内存进行了映射,使得每个进程都有独立的地址空间。当物理内存不足时,Linux内核会通过页面置换算法将暂时不使用的页写入磁盘交换空间,以释放物理内存供其他进程使用。 在文件系统管理方面,Linux内核支持多种文件系统,包括传统的ext3和ext4文件系统,以及现代的Btrfs和XFS文件系统。它负责文件的读写操作,以及文件的权限控制和磁盘空间的管理。 Linux内核的工作原理可以简单概括为以下几个步骤:首先,启动引导程序将内核加载到内存中,并进行初始化。然后,内核分配一部分内存作为内核空间,用于存放内核代码和数据结构。接着,内核根据系统的硬件配置进行设备的初始化和驱动程序的加载。之后,内核根据系统的启动参数和配置文件进行一系列的初始化工作,包括启动系统服务和加载用户程序。最后,内核进入主循环,不断地处理中断、调度进程、管理内存和文件系统,以提供稳定的操作系统服务。 总之,Linux内核是一个复杂而高效的软件系统,它通过进程管理、内存管理和文件系统管理等功能,实现了操作系统的基本功能。了解Linux内核的架构和工作原理,有助于我们更好地理解和使用这个优秀的开源操作系统。 ### 回答3: Linux内核是一个开放源代码的操作系统内核,由一个核心程序和一组通用的系统工具组成。它是Linux操作系统的核心,负责处理硬件设备、管理系统资源、实现进程管理、文件系统和网络功能等。 Linux内核的架构可以分为两个层次:用户空间和内核空间。用户空间包括用户应用程序,如图形界面、终端程序等,它们通过系统调用接口与内核进行通信。内核空间包括内核核心的数据结构和程序,用于管理和控制硬件资源。 Linux内核的工作原理可以概括为以下几个方面: 1. 进程管理:内核负责创建、调度和终止进程。它使用进程描述符(task_struct)来跟踪进程的状态和资源使用情况,并根据调度算法分配CPU时间片给不同的进程。 2. 内存管理:内核负责管理系统的物理内存和虚拟内存。物理内存管理包括内存分配和释放,虚拟内存管理包括页面置换和页面回写等策略,以优化内存的使用效率。 3. 文件系统:内核提供文件系统接口,管理文件和目录的创建、读写和删除等操作。它通过虚拟文件系统层(VFS)将不同的文件系统统一管理,如ext4、NTFS等。 4. 设备驱动:内核提供了访问硬件设备的接口,通过设备驱动程序与硬件交互。不同的硬件设备需要不同的驱动程序,如网卡、显卡、声卡等。 5. 网络功能:内核提供TCP/IP协议栈和网络设备驱动程序,用于实现网络通信功能。它提供网络连接的建立、数据传输和断开等功能,支持各种网络协议,如HTTP、FTP、SSH等。 总的来说,Linux内核是一个非常复杂且功能强大的软件,它负责管理计算机的各种资源和提供操作系统的各种功能。通过深入理解其架构和工作原理,我们可以更好地理解和使用Linux操作系统。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小巫技术博客

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值