前语

因事务需求,过去一年从了解的Android开发开始涉及嵌入式Linux开发,编程言语也从Java/Kotlin变成难上手的C++,这里边其实有许多差异点,特此整理本文来详细比照这两者开发的异同,便于对嵌入式Linux开发感兴趣的同学一些参阅。 本文纯抛转引玉,关于嵌入式领域笔者也是在逐渐学习中,如有讹夺欢迎补充。

适用人群

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

思维导图

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

架构比照

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

注:左边是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效果如下:

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

跨进程通讯比照

在Android和Linux体系中,跨进程通讯(IPC)是一种用于在不同进程之间传递数据和音讯的机制。以下是Android和Linux中跨进程通讯的比照:

维度 Android IPC Linux 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开发非常重要的知识点,原理图如下所示:

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

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

Binder的优势在于供给一种高功能、稳定性和安全性跨进程通讯机制。根据C/S架构,职责明晰、架构明晰;通讯进程中仅需求进行一次内存复制,功能仅次于同享内存;但是它为每个APP进程分配UID,能够经过UID辨别身份。

D-Bus
D-BUS是一种进程间通讯(IPC)机制,一般首要用于根据AF_UNIX套接字的本地进程间通讯(local IPC)(当然也能够根据TCP/IP)完成跨主机的通讯。原理图如下所示:

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

图片引自:hustcat.github.io/getting-sta…

D-Bus协议是一个端到端的通讯协议,核心基础概念参阅:

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

编程言语比照

参数 Java Kotlin C++
历史 1995年由James Gosling 在 Sun Microsystems 开发 2011年由JetBrains开发 1979年由Bjarne Stroustrup 在贝尔实验室开发
编程范式 面向对象 面向对象和函数式编程 面向进程和面向对象
渠道依靠 渠道无关 渠道无关 渠道相关
编译与解说 编译解说 编译解说 仅编译
内存办理 体系操控 体系操控 手动操控
可移植性 可移植 可移植 不可移植
指针 有限支撑 不支撑 强烈支撑
参数传递 按值传递 按值传递 按值传递和按引证传递
重载 仅办法重载 运算符和办法重载 运算符和办法重载
线程支撑 内置线程支撑 内置线程支撑 依靠第三方线程库
文档注释 支撑 支撑 不支撑
兼容性 不兼容其他言语 兼容Java 兼容C言语
goto语句 不支撑 不支撑 支撑
多重继承 单继承 单继承 单继承和多继承
结构体与共用体 不支撑 支撑数据类 支撑
虚拟要害字 一切非静态办法默许virtual 不支撑virtual要害字 支撑virtual要害字
硬件 离硬件较远 离硬件较远 挨近硬件
数据与功用 需在类中,可有包效果域 需在类中,可有包效果域 供给大局效果域和命名空间效果域
运转时错误检测 体系处理 体系处理 程序员处理
根层次结构 支撑单根层次结构 支撑单根层次结构 无根层次结构
输入输出 System.in 和 System.out.println println和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 APK Linux可执行文件
文件格局 APK(Android Package) ELF(可执行和可链接格局)
用处 Android运用程序的装置包 Linux体系上的可执行程序
打包内容 运用程序代码、资源、清单文件等 可执行代码、数据、符号表等
代码类型 Java/Kotlin字节码、C/C++库(可选) 一般为编译后的机器代码
运转环境 Android运转时(ART)或Dalvik虚拟机 直接在Linux操作体系上运转
装置进程 经过运用商铺或ADB装置到Android设备上 经过包办理器、编译装置或手动复制到体系目录
更新机制 经过运用商铺主动更新或手动更新 经过包办理器更新或手动替换可执行文件
安全和权限 Android权限模型、运用签名 Linux用户/组权限、文件权限等

APK文件一览:

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

Android Studio 剖析apk:

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

Linux中ELF可执行文件一览:

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

功能剖析东西比照

项目 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需求学习的内容的确还不少,但研制思路是迥然不同的,大致便是经过开发结构和编程言语安排代码,经过跨进程通讯来完成服务之间的调用,经过编译东西编译成能在体系运转环境的可执行文件,然后你需求重视如何进行运用更新,需求针对跑起来的运用进行功能剖析等等。当然实际的研制工作会愈加杂乱,要完成一个可商用的产品需求结合事务做更多的能力拓展,比方增加日志上报、溃散捕获、网络组件、存储组件、异步编程组件等等。