写点什么

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

作者:巫山老妖
  • 2023-12-17
    广东
  • 本文字数:3839 字

    阅读完需:约 13 分钟

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

前言

因业务需要,过去一年从熟悉的 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 的 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 中跨进程通信的对比:



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



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


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


D-Bus


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



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


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



编程语言对比


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 开发:


  • 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 开发中,包管理和依赖管理是两个相关的概念,它们共同处理应用程序或系统所需的库、组件和资源。以下是它们在包管理和依赖管理方面的主要区别:


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 可执行文件的对比:



APK 文件一览:



Android Studio 分析 apk:



Linux 中 ELF 可执行文件一览:



性能分析工具对比


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

写在最后

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


发布于: 刚刚阅读数: 6
用户头像

巫山老妖

关注

不总结哪来的经验,不分享经验有何用? 2018-02-22 加入

专注于移动开发领域,公众号【巫山老妖】。

评论

发布
暂无评论
一文搞懂Android和嵌入式Linux开发差异点_巫山老妖_InfoQ写作社区