前语
因事务需求,过去一年从了解的Android开发开始涉及嵌入式Linux开发,编程言语也从Java/Kotlin变成难上手的C++,这里边其实有许多差异点,特此整理本文来详细比照这两者开发的异同,便于对嵌入式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体系中,跨进程通讯(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开发非常重要的知识点,原理图如下所示:
Binder的优势在于供给一种高功能、稳定性和安全性跨进程通讯机制。根据C/S架构,职责明晰、架构明晰;通讯进程中仅需求进行一次内存复制,功能仅次于同享内存;但是它为每个APP进程分配UID,能够经过UID辨别身份。
D-Bus
D-BUS是一种进程间通讯(IPC)机制,一般首要用于根据AF_UNIX套接字的本地进程间通讯(local IPC)(当然也能够根据TCP/IP)完成跨主机的通讯。原理图如下所示:
D-Bus协议是一个端到端的通讯协议,核心基础概念参阅:
编程言语比照
参数 | 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之间的最大差异在于它们的编程范式、内存办理和渠道依靠性。
- 编程范式:C++支撑面向进程和面向对象编程,而Java和Kotlin首要支撑面向对象编程。Kotlin还支撑函数式编程。
- 内存办理:C++需求程序员手动办理内存分配和开释,而Java和Kotlin运用主动内存办理(垃圾回收机制),这使得Java和Kotlin更易于运用,但可能在某些情况下献身了功能。
- 渠道依靠性: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包办理和依靠办理:
- APK(Android Package Kit):这是Android运用程序的装置包格局,包含了运用程序的一切代码、资源、证书以及清单文件等。
- 运用商铺:Android运用程序一般经过运用商铺(如Google Play、华为运用商场等)进行分发和更新。运用商铺担任运用程序的审核、签名、装置、更新等功用。
- Gradle:Android Studio运用Gradle作为构建体系,它担任处理运用程序的依靠联系。开发者能够在项目的build.gradle文件中声明所需的第三方库,Gradle会主动从远程库房(如Maven Central、JCenter等)下载并集成这些库。
- Android SDK/NDK:Android SDK供给了一套用于开发Android运用程序的API和组件,而Android NDK供给了一套用于处理本地C/C++代码依靠联系的东西。这些组件已经包含在Android体系中,无需额外处理依靠联系。
嵌入式Linux包办理和依靠办理:
- 包格局:嵌入式Linux体系的包格局取决于详细的发行版,如Debian/Ubuntu运用deb包,Red Hat/CentOS运用RPM包,OpenWrt运用opkg包等。
- 软件库房:嵌入式Linux运用程序一般经过软件库房进行分发和更新。软件库房是一个包含了预编译软件包的服务器,用户能够经过包办理器(如apt、yum、opkg等)从软件库房装置和更新软件包。
- 包办理器:嵌入式Linux发行版一般供给了一个包办理器(如apt、yum、opkg等),用于主动处理体系和运用程序的依靠联系。开发者能够经过包办理器从软件库房装置所需的库和组件。
- 构建体系:嵌入式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 Studio 剖析apk:
Linux中ELF可执行文件一览:
功能剖析东西比照
项目 | 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需求学习的内容的确还不少,但研制思路是迥然不同的,大致便是经过开发结构和编程言语安排代码,经过跨进程通讯来完成服务之间的调用,经过编译东西编译成能在体系运转环境的可执行文件,然后你需求重视如何进行运用更新,需求针对跑起来的运用进行功能剖析等等。当然实际的研制工作会愈加杂乱,要完成一个可商用的产品需求结合事务做更多的能力拓展,比方增加日志上报、溃散捕获、网络组件、存储组件、异步编程组件等等。