首页 > 语言 > 关键词  > 移动开发技术最新资讯  > 正文

聊聊移动端跨平台开发的各种技术

2015-05-12 10:22 · 稿源: 百度Fex

介绍

最近出现的 React Native 再次让跨平台移动端开发这个话题火起来了,曾经大家以为在手机上可以像桌面那样通过 Web 技术来实现跨平台开发,却大多因为性能或功能问题而放弃,不得不针对不同平台开发多个版本。

但这并没有阻止人们对跨平台开发技术的探索,毕竟谁不想降低开发成本,一次编写就处处运行呢?除了 React Native,这几年还出现过许多其它解决方案,本文我将会对这些方案进行技术分析,供感兴趣的读者参考。

为了方便讨论,我将它们分为了以下 4 大流派:

  • Web 流:也被称为 Hybrid 技术,它基于 Web 相关技术来实现界面及功能
  • 代码转换流:将某个语言转成 Objective-C、Java 或 C#,然后使用不同平台下的官方工具来开发
  • 编译流:将某个语言编译为二进制文件,生成动态库或打包成 apk/ipa/xap 文件
  • 虚拟机流:通过将某个语言的虚拟机移植到不同平台上来运行

Web 流

Web 流是大家都比较了解的了,比如知名的 PhoneGap/Cordova,它将原生的接口封装后暴露给 JavaScript,可以运行在系统自带的 WebView 中,也可以自己内嵌一个 Chrome 内核 。

作为这几年争论的热点,网上已经有很多关于它的讨论了,这里我重点聊聊大家最关心的性能问题。

Web 流最常被吐槽的就是性能慢(这里指内嵌 HTML 的性能,不考虑网络加载时间),可为什么慢呢?常见的看法是认为「DOM 很慢」,然而从浏览器实现角度来看,其实 DOM 就是将对文档操作的 API 暴露给了 JavaScript,而 JavaScript 的调用这些 API 后就进入内部的 C++ 实现了,这中间并没有多少性能消耗,所以从理论上来说浏览器的 DOM 肯定比 Android 的「DOM」快,因为 Android 的展现架构大部分功能是用 Java 写的,在实现相同功能的前提下,C++ 不大可能比 Java 慢(某些情况下 JIT 编译优化确实有可能做得更好,但那只是少数情况)。

所以从字面意思上看「DOM 很慢」的说法是错误的,这个看法之所以很普遍,可能是因为大部分人对浏览器实现不了解,只知道浏览器有 DOM,所以不管什么问题都只能抱怨它了。

那么问题在哪呢?在我看来有三方面的问题:

  • 早期浏览器实现比较差,没有进行优化
  • CSS 过于复杂,计算起来更耗时
  • DOM 提供的接口太有限,使得难以进行优化

首先个问题是最关键也是最难解决的,现在说到 Web 性能差主要说的是 Android 下比较差,在 iOS 下已经很流畅了,在 Android 4 之前的 WebView 甚至都没有实现 GPU 加速,每次重绘整个页面,有动画的时候不卡才怪。

浏览器实现的优化可以等 Android 4.4 慢慢普及起来,因为 4.4 以后就使用 Chrome 来渲染了。

而对于比较新的浏览器来说,渲染慢的原因就主要是第二个问题:CSS 过于复杂,因为从实现原理上看 Chrome 和 Android View 并没有本质上的差别,但 CSS 太灵活功能太多了,所以计算成本很高,自然就更慢了。

那是不是可以通过简化 CSS 来解决?实际上还真有人这么尝试了,比如 Famo.us,它比较大的特色就是不让你写 CSS,只能使用固定的几种布局方法,完全靠 JavaScript 来写界面,所以它能有效避免写出低效的 CSS,从而提升性能。

而对于复杂的界面及手机下常见的超长的 ListView 来说,第三个问题会更突出,因为 DOM 是一个很上层的 API,使得 JavaScript 无法做到像 Native 那样细粒度的控制内存及线程,所以难以进行优化,则在硬件较差的机器上会比较明显。对于这个问题,我们一年前曾经尝试过嵌入原生组件的方式来解决,不过这个方案需要依赖应用端的支持,或许以后浏览器会自带几个优化后的 Web Components 组件,使用这些组件就能很好解决性能问题。

现阶段这三个问题都不好解决,所以有人想干脆不用 HTML/CSS,自己来画界面,比如 React canvas 直接画在 Canvas 上,但在我看来这只是现阶段解决部分问题的方法,在后面的章节我会详细介绍自己画 UI 的各种问题,这里说个历史吧,6 年前浏览器还比较慢的时候,Bespin 就这么干过,后来这个项目被使用 DOM 的 ACE 取代了,目前包括 TextMirror 和 Atom 在内的主流编辑器都是直接使用 DOM,甚至 W3C 有人专门写了篇文章吐槽用 Canvas 做编辑器的种种缺点,所以使用 Canvas 要谨慎。

另外除了 Canvas,还有人以为 WebGL 快,就尝试绘制到 WebGL 上,比如 HTML-GL,但它目前的实现太偷懒了,简单来说就是先用 html2canvas 将 DOM 节点渲染成图片,然后将这个图片作为贴图放在 WebGL 中,这等于将浏览器中用 C++ 写的东东在 JavaScript 里实现了一遍,渲染速度肯定反而更慢,但倒是能用 GLSL 做有效来忽悠人。

硬件加速不等同于「快」,如果你以为硬件加速一定比软件快,那你该抽空学学计算机体系结构了

其实除了性能问题,我认为在 Web 流更严重的问题是功能缺失,比如 iOS 8 就新增 4000+ API,而 Web 标准需要漫长的编写和评审过程,根本赶不上,即便是 Cordova 这样自己封装也忙不过来,所以为了更好地使用系统新功能,写 Native 代码是必须的。

代码转换流

前面提到写 Native 代码是必须的,但不同平台下的官方语言不一样,这会导致同样的逻辑要写两次以上,于是就有人想到了通过代码转换的方式来减少工作量,比如将 Java 转成 Objective-C。

这种方式虽然听起来不是很靠谱,但它却是成本和风险都最小的,因为代码转换后就可以用官方提供的各种工具了,和普通开发区别不大,因此不用担心遇到各种诡异的问题,不过需要注意生成的代码是否可读,不可读的方案就别考虑了。

接下来看看目前存在的几种代码转换方式。

将 Java 转成 Objective-C

j2objc 能将 Java 代码转成 Objective-C,据说 Google 内部就是使用它来降低跨平台开发成本的,比如 Google Inbox 项目就号称通过它共用了 70% 的代码,效果很显著。

可能有人会觉得奇怪,为何 Google 要专门开发一个帮助大家写 Objective-C 的工具?还有媒体说 Google 做了件好事,其实吧,我觉得 Google 这算盘打得不错,因为基本上重要的应用都会同时开发 Android 和 iOS 版本,有了这个工具就意味着,你可以先开发 Android 版本,然后再开发 iOS 版本。。。

既然都有成功案例了,这个方案确实值得尝试,而且关键是会 Java 的人多啊,可以通过它来快速移植代码到 Objective-C 中。

将 Objective-C 转成 Java

除了有 Java 转成 Objective-C,还有 Objective-C 转成 Java 的方案,那就是 MyAppConverter,比起前面的 j2objc,这个工具更有野心,它还打算将 UI 部分也包含进来,从它已转换的列表中可以看到还有 UIKit、CoreGraphics 等组件,使得有些应用可以不改代码就能转成功,不过这点我并不看好,对于大部分应用来说并不现实。

由于目前是收费项目,我没有尝试过,对技术细节也不了解,所以这里不做评价。

将 Java 转成 C#

Mono 提供了一个将 Java 代码转成 C# 的工具 Sharpen,不过似乎用的人不多,Star 才 118,所以看起来不靠谱。

还有 JUniversal 这个工具可以将 Java 转成 C#,但目前它并没有发布公开版本,所以具体情况还待了解,它的一个特色是自带了简单的跨平台库,里面包括文件处理、JSON、HTTP、OAuth 组件,可以基于它来开发可复用的业务逻辑。

比起转成 Objective-C 和 Java 的工具,转成 C# 的这两个工具看起来都非常不成熟,估计是用 Windows Phone 的人少。

将 Haxe 转成其它语言

说到源码转换就不得不提 Haxe 这个奇特的语言,它没有自己的虚拟机或可执行文件编译器,所以只能通过转成其它语言来运行,目前支持转成 Neko(字节码)、Javascript、Actionscript 3、PHP、C++、Java、C# 和 Python,尽管有人实现了转成 Swift 的支持,但还是非官方的,所以要想支持 iOS 开发目前只能通过 Adobe AIR 来运行。

在游戏开发方面做得不错,有个跨平台的游戏引擎 OpenFL 的,最终可以使用 HTML5 Canvas、OpenGL 或 Flash 来进行绘制,OpenFL 的开发体验做得相当不错,同一行代码不需要修改就能编译出不同平台下的可执行文件,因为是通过转成 C++ 方式进行编译的,所以在性能和反编译方面都有优势,可惜目前似乎并不够稳定,不然可以成为 Cocos2d-x 的有利竞品。

在 OpenFL 基础上还有个跨平台的 UI 组件 HaxeUI,但界面风格我觉得特别丑,也就只能在游戏中用了。

所以目前来看 Haxe 做跨平台游戏开发或许可行,但 APP 开发就别指望了,而基于它来共用代码实在就更不靠谱了,因为熟悉它的开发者极少,反而增加成本。

XMLVM

除了前面提到的源码到源码的转换,还有 XMLVM 这种与众不同的方式,它首先将字节码转成一种基于 XML 的中间格式,然后再通过 XSL 来生成不同语言,目前支持生成 C、Objective-C、JavaScript、C#、Python 和 Java。

虽然基于一个中间字节码可以方便支持多语言,然而它也导致生成代码不可读,因为很多语言中的语法糖会在字节码中被抹掉,这是不可逆的,以下是一个简单示例生成的 Objective-C 代码,看起来就像汇编:

XMLVM_ENTER_METHOD("org.xmlvm.tutorial.ios.helloworld.portrait.HelloWorld", "didFinishLaunchingWithOptions", "?")XMLVMElem _r0;XMLVMElem _r1;XMLVMElem _r2;XMLVMElem _r3;XMLVMElem _r4;XMLVMElem _r5;XMLVMElem _r6;XMLVMElem _r7;_r5.o = me;_r6.o = n1;_r7.o = n2;_r4.i = 0;_r0.o = org_xmlvm_iphone_UIScreen_mainScreen__();XMLVM_CHECK_NPE(0)_r0.o = org_xmlvm_iphone_UIScreen_getApplicationFrame__(_r0.o);_r1.o = __NEW_org_xmlvm_iphone_UIWindow();XMLVM_CHECK_NPE(1)...

在我看来这个方案相当不靠谱,万一生成的代码有问题基本没法修改,也没法调试代码,所以不推荐。

小结

虽然代码转换这种方式风险小,但我觉得对于很多小 APP 来说共享不了多少代码,因为这类应用大多数围绕 UI 来开发的,大部分代码都和 UI 耦合,所以公共部分不多。

在目前的所有具体方案中,只有 j2objc 可以尝试,其它都不成熟。

编译流

编译流比前面的代码转换更进一步,它直接将某个语言编译为普通平台下的二进制文件,这种做法有明显的优缺点:

  • 优点
    • 可以重用一些实现很复杂的代码,比如之前用 C++ 实现的游戏引擎,重写一遍成本太高
    • 编译后的代码反编译困难
    • 或许性能会好些(具体要看实现)
  • 缺点
    • 如果这个工具本身有 Bug 或性能问题,定位和修改成本会很高
    • 编译后体积不小,尤其是如果要支持 ARMv8 和 x86 的话

接下来我们通过区分不同语言来介绍这个流派下的各种方案。

C++ 类

C++ 是最常见的选择,因为目前 Android、iOS 和 Windows Phone 都提供了 C++ 开发的支持,它通常有三种做法:

  • 只用 C++ 实现非界面部分,这是官方比较推崇的方案,目前有很多应用是这么做的,比如 Mailbox 和 Microsoft Office。
  • 使用 2D 图形库来自己绘制界面,这种做法在桌面比较常见,因为很多界面都有个性化需求,但在移动端用得还不多。
  • 使用 OpenGL 来绘制界面,常见于游戏中。

使用 C++ 实现非界面部分比较常见,所以这里就不重复介绍了,除了能提升性能和共用代码,还有人使用这种方式来隐藏一些关键代码(比如密钥),如果你不知道如何构建这样的跨平台项目,可以参考 Dropbox 开源的 libmx3 项目,它还内嵌了 json 和 sqlite 库,并通过调用系统库来实现对简单 HTTP、EventLoop 及创建线程的支持。

而如果要用 C++ 实现界面部分,在 iOS 和 Windows Phone 下可以分别使用 C++ 的超集 Objective-C++ 和 C++/CX,所以还比较容易,但在 Android 下问题就比较麻烦了,主要原因是 Android 的界面绝大部分是 Java 实现的,所以用 C++ 开发界面比较大的挑战是如何支持 Android,这有两种做法:通过 JNI 调用系统提供的 Java 方法或者自己画 UI。

首先种做法虽然可行,但代码太冗余了比如一个简单的函数调用需要写那么多代码:

JNIEnv* env;jclass testClass = (*env)->FindClass(env, "com/your/package/name/Test"); 
// get ClassjmethodID constructor = (*env)->GetMethodID(env, cls, "", "()V");jobject testObject = (*env)->NewObject(env, testClass, constructor);methodID callFromCpp = (*env)->GetMethodID(env, testClass, "callFromCpp", "()V");
//get methodid(*env)->CallVoidMethod(env, testObject, callFromCpp);

那自己画 UI 是否会更方便点?比如 JUCE 和 QT 就是自己画的,我们来看看 QT 的效果:

看起来很不错是吧?不过在 Android 5 下就悲剧了,很多效果都没出来,比如按钮没有涟漪效果,甚至边框都没了,根本原因在于它是通过 Qt Quick Controls 的自定义样式来模拟的,而不是使用系统 UI 组件,因此它享受不到系统升级自动带来的界面优化,只能自己再实现一遍,工作量不小。

反而如果最开始用的是 Android 原生组件就什么都不需要做,而且还能用新的 AppCompat 库来在 Android 5 以下实现 Material Design 效果。

最后一种做法是使用 OpenGL 来绘制界面,因为 EGL+OpenGL 本身就是跨平台,所以基于它来实现会很方便,目前大多数跨平台游戏底层都是这么做的。

既然可以基于 OpenGL 来开发跨平台游戏,是否能用它来实现界面?当然是可行的,而且 Android 4 的界面就是基于 OpenGL 的,不过它并不是只用 OpenGL 的 API,那样是不现实的,因为 OpenGL API 最初设计并不是为了画 2D 图形的,所以连画个圆形都没有直接的方法,因此 Android 4 中是通过 Skia 将路径转换为位置数组或纹理,然后再交给 OpenGL 渲染的。

然而要完全实现一遍 Android 的 UI 架构工作量不小,以下是其中部分相关代码的代码量:

其中光是文字渲染就非常复杂,如果你觉得简单,那只能说明你没看过这个世界有多大,或许你知道中文有编码问题、英语有连字符(hyphen)折行,但你是否知道繁体中文有竖排版、阿拉伯文是从右到左的、日语有平假名注音(ルビ)、印度语有元音附标文字(abugida አቡጊዳ)……?

而相比之下如果每个平台单独开发界面,看似工作量不小,但目前在各个平台下都会有良好的官方支持,相关工具和文档都很完善,所以其实成本没那么高,而且可以给用户和系统风格保持一致的良好体验,所以我认为对于大多数应用来说自己画 UI 是很不划算的。

不过也有特例,对于 UI 比较独特的应用来说,自己画也是有好处的,除了更灵活的控制,它还能使得不同平台下风格统一,这在桌面应用中很常见,比如 Windows 下你会发现几乎每个必备软件的 UI 都不太一样,而且好多都有换肤功能,在这种情况下很适合自己画 UI。

举报

  • 相关推荐
  • 浙江文交所与鲸探携手“科技+文化” 实现文化数字资产跨平台“秒转”流通

    7月7日,浙江文交所与蚂蚁集团旗下鲸探科技达成合作,推出数字资产跨系统"秒转"功能,实现数字藏品在数文链和蚂蚁链间的便捷互转。首批支持《愤怒小鱼篓》等5款藏品跨平台流通,并同步发行文旅数字藏品《东坡行旅·石刻踪迹》1.2万份。此次合作创新"瞬时交割"交易模式,推动数字资产跨平台智能流通,促进文化数字资产市场繁荣发展。未来双方将深化合

  • GCDG丨江阴站:AI赋能,开发者技术沙龙圆满举办!

    2025年6月8日,葡萄城开发者社区在江苏举办"AI赋能·开发者技术交流会"。活动汇聚多地开发者,共同探讨AI+低代码创新实践。开发者谷凯展示如何利用GPT-4等AI工具提升开发效率,强调独立开发者"一人也能创造价值"的理念。钟代冬分享家纺电商低代码工程案例,展示活字格平台实现复杂任务自动化运维的能力。技术顾问薛禹坤介绍"All-in-One一站式智能体开发"理念,演示活字格V11.0新版本AI功能。活动促进跨地域、跨领域思维碰撞,为开发者搭建紧密连接平台,推动前沿技术交流与实践经验分享。

  • 玄武云出席崔牛会AI活动,聊聊AI大模型如何掌握终端信息

    6月20日,崔牛会主办的AI发现者计划之AI+OPEN DAY在广州举办,玄武云与百度云等企业围绕AI大模型应用展开探讨。玄武云分享了快消行业数字化转型解决方案,推出SKU超级模型和价签识别模型,帮助品牌商提升终端管理效率。其中SKU模型覆盖6000+商品,识别准确率达90%;价签模型准确率85%,已应用于知名薯片品牌。通过AI技术实现商品陈列优化、价格监控和渠道布局分析,助力快消企业从经验驱动转向数据智能驱动,在存量市场中创造增量价值。

  • 数字人带货5000万,电商平台打响AI技术军备赛

    ​6月15日,罗永浩数字人在百度电商完成首场直播,吸引超1300万人次观看,GMV突破5500万元,创下数字人直播带货新纪录。 在这场头部主播数字人首秀中,AI起着关键作用,不仅驱动数字人做出8300个动作,还生成高达9.7万字的剧本式产品讲解,连罗永浩本人都说:“如果没有数字人,这得把我累成啥样!” 事实上,“头部主播+AI”带货的新尝试,背后是AI正在全面渗透电商平台�

  • HDC2025丨华为推出小艺智能体开放平台,全面赋能鸿蒙智能体开发

    6月20日,华为在开发者大会2025上发布鸿蒙智能体框架(HMAF)及白皮书,标志着鸿蒙系统全面进入Agent时代。该框架定义了操作系统、应用与智能体的交互模式,支持自主决策与群体协作的AI生态。小艺智能体作为系统级中枢,可拆解复杂任务并调度多智能体协同完成。同时推出小艺智能体开放平台,提供全链路开发方案,支持50+系统插件和自然语言创建工作流。目前已有50+鸿蒙智能体即将上线,覆盖天气、音乐、资讯等场景。华为表示,鸿蒙智能体将带来更高效、自主的人机交互新模式,未来将持续开放AI能力,与开发者共建智能生态。

  • @开发者们:百度文心大模型4.5系列模型开源,国内首发平台GitCode现已开放下载!

    6月30日,百度文心大模型4.5系列正式开源并在国内领先的开源平台GitCode首发上线。该系列包含10款模型,涵盖47B和3B参数的混合专家(MoE)模型及0.3B的稠密参数模型,采用创新的多模态异架构结构实现跨模态知识融合。模型基于飞桨框架开发,训练效率达47% MFU,在文本和多模态基准测试中达到SOTA水平。所有模型按Apache2.0协议开源,配套产业级开发套件支持多种芯片部署。GitCode平台已汇聚620万用户,为AI开发者提供代码托管、协同开发等全流程支持。此次开源将推动中国AI生态创新,加速大模型技术产业化应用。

  • Baidu Steamer-I2V推动视频生成技术突破,擎舵平台赋能原生创意营销

    百度推出全球领先的视频生成模型Baidu Steamer-I2V,以89.38%综合评分登顶VBench榜单。该模型通过精准画面控制、高清画质和中文语义优化,能将静态图像转化为连贯动态视频。百度营销平台迎来2周年,已服务超13万家企业,日均生产素材超10万+。在"AI驱动营销全链路升级"主题下,百度与核心代理商共同探讨AIGC技术突破与创意升级,推出"AI创"原生创意大赛。百度商业体系表示将持续巩固传统广告优势,同时突破创意边界,实现营销效果飞跃。未来百度将优化模型性能,拓展应用场景,推动营销行业迈向"一杯咖啡时间完成创意生产"的全智能化时代。

  • AI日报:阿里通义推Qwen-TTS模型;Cursor已支持网页和手机端;字节发布图像合成技术XVerse

    【AI日报】今日AI领域7大突破:1)阿里通义Qwen-TTS实现方言语音合成重大突破;2)Cursor发布Web版AI编程工具;3)字节XVerse技术实现多对象精准图像生成;4)NoteGen跨平台AI笔记工具革新知识管理;5)ManimML动画库可视化Transformer架构;6)TEN+Agent开源语音交互技术降低延迟;7)Chai-2抗体设计模型将药物研发周期缩短至两周。淘宝同时上线RecGPT推荐模型提升购物体验。

  • 金骨龄《儿童生长发育数字化管理平台》 荣获“雄安医疗大健康技术应用大赛”优秀奖

    "雄安医疗大健康技术应用大赛"近日落幕,聚焦AI、物联网等技术赋能医疗健康领域。大赛吸引全国442家企业和团队的604个项目参赛,覆盖智慧医疗、生物医药等多个前沿领域。河北医大二院与金骨龄联合研发的"儿童生长发育数字化管理平台"获优秀奖,该平台通过AI骨龄评价、疾病预警等功能实现儿童生长数字化管理,准确率达91.1%。平台采用"科研+临床"双驱动模式,整合省级专家资源,实现基层医院与上级医院联动,打破地域限制共享医疗资源。此次大赛为探索未来医疗新模式、助力雄安打造高端医疗服务中心提供了创新思路。

  • 发发奇平台怎么样?堪称奢侈品平台商业传奇

    FARFETCH(发发奇)从2023年濒临破产到2024年实现3000万美元盈利,完成华丽转身。其核心优势在于创新的"数字连接者"商业模式,通过轻资产技术平台串联全球3500个奢侈品牌和1300家买手店,既规避库存压力又保证商品稀缺性。平台拥有两大护城河:自主研发的库存同步系统和AI推荐算法确保全球商品实时更新与精准匹配;与1300家顶级买手店的长期合作保障稀缺单品供应。严格的商品三重认证体系带来99.7%的正品满意度。2023年被韩国电商巨头Coupang收购后,通过物流优化、关闭亏损业务等改革实现扭亏为盈。未来将借力Coupang深耕亚洲市场,从激进创新者转型为务实运营者。