一文搞懂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需要学习的内容确实还不少,但研发思路是大同小异的,大致就是通过开发框架和编程语言组织代码,通过跨进程通信来实现服务之间的调用,通过编译工具编译成能在系统运行环境的可执行文件,然后你需要关注如何进行应用更新,需要针对跑起来的应用进行性能分析等等。当然实际的研发工作会更加复杂,要实现一个可商用的产品需要结合业务做更多的能力拓展,比如增加日志上报、崩溃捕获、网络组件、存储组件、异步编程组件等等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/251619.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java 多线程学习(三)

目录 一、多线程 1、深入synchronized 1.1、synchronized的优化 1.2、synchronized实现原理 1.3、synchronized的锁升级 1.4、重量锁底层ObjectMonitor 一、多线程 1、深入synchronized 1.1、synchronized的优化 在JDK1.5的时候,Doug Lea推出了ReentrantLoc…

Redis核心知识小结

基础 redis为什么快呢? 单线程基于io多路复用底层C语言对数据结构做了优化完全内存的操作 Redis6.0使用多线程是怎么回事? Redis不是说用单线程的吗?怎么6.0成了多线程的? Redis6.0的多线程是用多线程来处理数据的读写和协议解析&#x…

【算法笔记】动态规划,使用最小花费爬楼梯,详细刨析。

1.题目描述 给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。 你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。 请你计算并返回达到楼梯顶部的最低花费。 示…

linux 开机启动流程

1.打开电源 2.BIOS 有时间和启动方式 3.启动Systemd 其pid为1 4.挂载引导分区 /boot 5.启动各种服务 如rc.local

STM32 EC200 物联网项目实操 第2篇 FTP OTA升级

背景: 做了个物联网项目,需要做个OTA升级,程序分为两部分,一部分是BOOT引导程序,一部是主程序,在BOOT引导程序里面实现了和EC200 4G模块通讯,和FTP服务器通讯,获取OTA升级BIN文件。主…

【前端八股】系列之性能指标与评估工具

【前端八股】系列之性能指标与评估工具 前言性能指标的定义和特性性能指标的分类实验室指标真实指标用户感知指标评估工具 前言 这里是以前自己关于性能指标与评估工具的相关笔记,下面主要是关于性能指标的定义与特性以及相关的评估工具,并没有记录深入…

人工智能_机器学习065_SVM支持向量机KKT条件_深度理解KKT条件下的损失函数求解过程_公式详细推导---人工智能工作笔记0105

之前我们已经说了KKT条件,其实就是用来解决 如何实现对,不等式条件下的,目标函数的求解问题,之前我们说的拉格朗日乘数法,是用来对 等式条件下的目标函数进行求解. KKT条件是这样做的,添加了一个阿尔法平方对吧,这个阿尔法平方肯定是大于0的,那么 可以结合下面的文章去看,也…

mysql8支持远程访问

上面的localhost要改为%号就打开了远程访问 ALTER USER root% IDENTIFIED WITH mysql_native_password BY fengzi2141;

vite原理

一、依赖预构建 1、为什么需要依赖预构建 CommonJS和UMD兼容性 在开发阶段中,vite的开发服务器将所有的代码视为原生ES模块。因此,vite必须先将作为CommonJS或者UMD发布的依赖项转换为ESM。 这是vite的一个特色,也是为什么会相对于webpack比…

Android动画(一)——逐帧动画

目录 介绍 Android动画类型分类 逐帧动画 逐帧动画的使用 效果图 介绍 Android动画是一种用于创建视觉效果和交互体验的技术,可以增强用户界面的吸引力和响应性。Android提供了丰富的动画框架和API,使开发者可以轻松地添加动画效果到他们的应用程序中…

n维随机变量、n维随机变量的分布函数

设随机试验E的样本空间是,其中表示样本点。 设是定义在上的随机变量,由它们构成一个n维向量,叫做n维随机向量,也叫n维随机变量。 对于任意n个实数,n元函数 称为n维随机变量的分布函数,也叫联合分布函数。

springCloud项目打包如何把jar放到指定目录下

springCloud项目打包如何把jar发放到指定目录下 maven-antrun-plugin springCloud微服务打包jar,模块过多;我的项目模块结构如下: 我把实体类相关的单独抽离一个模块在service-api下服务单独写在service某块下, 每个模块的jar都…

【C++】 C++11 新特性探索:decltype 和 auto

▒ 目录 ▒ 🛫 问题描述环境 1️⃣ decltype推导变量类型推导函数返回类型 2️⃣ auto自动推导变量类型迭代器和范围循环 3️⃣ decltype 和 auto 同时使用🛬 结论📖 参考资料 🛫 问题 描述 C11 引入了一些强大的新特性&#xff…

【python】Debian安装miniconda、spyder、tushare

1. miniconda 安装 — 动手学深度学习 2.0.0 documentation中有安装Miniconda的一些说明。 Miniconda — miniconda documentation是Miniconda网站,里面也有安装说明。 Debian安装按照linux安装即可: mkdir -p ~/miniconda3 wget https://repo.anaco…

软实力篇---第五篇

系列文章目录 文章目录 系列文章目录前言一、HR 最喜欢问程序员的 20 个问题二、面试中的礼仪与举止前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 一、HR 最喜欢…

机器学习---协同过滤

协同过滤(Collaborative Filtering)技术,是推荐系统中应用最为广泛的技术之一,协同过滤算法主要有两种,一种是基于用户的协同过滤算法(UserBaseCF),另一种是基于物品的协同过滤算法(ItemBaseCF)…

直接插入排序_希尔排序

文章目录 直接插入排序原理步骤视频演示代码实现特性 希尔排序原理步骤图像演示代码实现希尔排序的分析特性 直接插入排序和希尔排序的比较 直接插入排序 直接插入排序(Straight InsertionSort)是一种最简单的排序方法,其基本操作是将一条记录…

腾讯云:AI云探索之路

随着科技的飞速发展,人工智能(AI)云计算领域日益显现出其巨大的潜力和价值。在这个充满挑战和机遇的领域,腾讯云凭借其卓越的技术和创新能力,取得了令人瞩目的成果。本文将深入探讨腾讯云在AI云计算领域的优势,以及其为人工智能发…

Multi-sensor KIT-V3.0 多传感器开发板

Multi-sensor KIT-V3.0 多传感器开发板 1.前言1.1 特点 2. Multi-sensor KIT QMA8658A-EVB QMC5883评估板的扩展2.1 特点 3. Multi-sensor KIT (QMA8658A-EVB QMC5883) Ultrasonic-CH-X01-EVB评估板的扩展3.1 特点 4.资料资源Multi-sensor KIT-V3.0 …

基于Hadoop的农产品价格信息检测分析系统

基于Hadoop的农产品价格信息检测分析系统 前言数据处理模块1. 数据爬取2. 数据清洗与处理3. 数据存储 数据分析与检测模块1. 农产品价格趋势分析2. 农产品价格检索3. 不同市场价格对比 创新点 前言 为了更好地了解农产品市场价格趋势和不同市场之间的价格差异,我设…