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

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

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万份。此次合作创新"瞬时交割"交易模式,推动数字资产跨平台智能流通,促进文化数字资产市场繁荣发展。未来双方将深化合

  • 融合数据中台与动态调度:林剑峰在共享出行智能算法开发中的技术探索

    本文讲述了林剑峰在智能出行领域的十年深耕历程。作为系统工程师,他主导构建了融合数据、算法与规则引擎的智能调度体系,通过动态聚类和路径规划模型显著提升了共享单车调度效率。其创新包括分级围栏模型、嵌入式调度判断模块等专利技术,实现了跨区域精准调度和系统自主运行能力。数据显示,他推动的系统使车辆调度效率提升37.38%,异常识别准确率显著提高。林剑峰的工作体现了"技术+业务"的系统设计理念,为城市智能交通建设提供了可借鉴的技术范式。

  • 企业如何低成本搭建可快速响应的远程技术支持平台?

    文章探讨了极端天气下企业技术支持的转型需求,重点介绍了远程技术支持的解决方案。传统线下服务面临出行困难、安全隐患等问题,而远程技术支持能实现设备监测、故障排查等操作,保障人员安全。贝锐向日葵推出的远程控制方案具有高效稳定、快速响应等特点,支持文件传输、工单流转等功能,并与ITSM平台深度整合,形成闭环服务体系。方案还提供团队版共享机制,适合初创团队低成本使用。在极端天气频发的当下,远程方案能显著提升企业抗灾能力,实现降本增效。

  • 北芯生命坚持自主研发与技术突破,为临床诊疗提供有力技术支撑

    深圳北芯生命科技通过自主研发,在心血管精准诊疗领域取得重大突破。其核心产品包括中国首个自主60MHz高清高速IVUS系统和首个获批的国产FFR系统,填补国内技术空白,改变依赖进口的局面。目前公司已推出11款产品,覆盖五大类别,其FFR系统上市后迅速占据30.6%国内市场份额。北芯构建了完整创新生态,产品广泛应用于国内30个省市的三甲医院,并逐步走向国际市场。未来公司将持续创新,为心血管疾病诊疗提供更智能的解决方案。

  • 国内MCP服务合集平台去哪看?MCP server资源平台推荐

    ​在当今人工智能技术飞速发展的时代,AI模型与外部工具和服务的交互能力正逐渐成为推动技术进步的关键因素。今天,我们聚焦于一个新兴的、极具潜力的平台——AIbase,它为全球的AI开发者和研究人员提供了一个前所未有的MCP(Model Context Protocol,模型上下文协议)服务器集合平台,助力AI技术的进一步发展。 AIbase平台致力于整合全球优质的MCP服务器资源,为开发者提供�

  • 苹果研发加速:至少7款自研处理器同步开发中

    据媒体报道,随着2025年下半年新品发布季临近,苹果公司正迎来其自研芯片战略的关键转折点。 最新行业消息显示,苹果正在同步开发7款全新处理器,覆盖移动计算、可穿戴设备和无线通信三大领域,标志着其技术自主化进程进入全新阶段。 在移动处理器方面,苹果将推出A19系列芯片组。其中标准版A19将首次搭载于代号Tilos的iPhone 17 Air机型,而性能更强的A19 Pro版本则会为i

  • 电商多平台大商家电商erp价格多少钱

    文章探讨了电商多平台大商家ERP系统的价格差异问题。作者公司在天猫、京东、抖音、拼多多等平台运营,日单量2万,人工表格管理已无法满足需求。调研发现同类ERP报价从3000到30万不等,最终选择了快麦ERP。该系统显著提升了运营效率:库存同步延迟从10分钟降至5秒,超卖损失减少80%;拣货效率提升50%,临时工减少1/3;财务对账时间从3天缩短至半小时。综合节省的人工、赔付和加班费用,远超系统本身价格。作者建议企业选择ERP时要全面核算隐性成本,而非仅比较报价。

  • AI仙侠玄幻剧:用离谱和技术给你们一点震撼

    凤凰男成“下蛋”工具、龙女一言不合就“炖妖”补身、“男妈”一胎诞下一窝小狐狸、“万妖窟”男团惨变“火锅底料”、铺垫老半天的“大boss”竟是Labubu……比离谱更离谱的AI仙侠玄幻短剧悄悄地火了。 《遮天》首播即爆,全网话题量破亿;抖音账号“梦婆婆”连载的《九尾狐男妖爱上我》目前累计播放量已超1.1亿,冲上抖音+快手短剧综合热度榜TOP20,“癫”感十足的剧�

  • 理想小米同一个地方开发布会:理想i8发布会定于首都国际会议中心

    近日,理想汽车CEO李想在社交平台发文透露,理想i8新车发布会将于7月29日在首都国际会议中心举行,并特别表示此次发布会将“向小米YU7致敬”,原因是二者选择了同一地点举办活动。 李想透露,过去几年,理想汽车旗下理想ONE、L6-L9等车型均选择在理想汽车园区内的草坪上发布,主要考虑因素是节省成本并提高效率。然而,此次理想i8作为理想进军纯电SUV领域的首款力作,

  • 推荐几个国内比较主流的API管理平台

    本文介绍了国内主流的API管理平台,包括Apifox、RestCloud iPaaS、YApi、API Umbrella、Postcat、白山云和数环通。这些平台各具特色:Apifox集文档、调试、Mock和测试于一体;RestCloud iPaaS支持AI助手和300+ SaaS应用连接;YApi适合跨语言开发团队;API Umbrella提供多团队协同和实时监控;Postcat轻量可扩展;白山云专注企业级全流程管理;数环通主打智能化自动化。企业应根据自身规模、行业需�