跨平台客户端开发经验总结

1 前言

因为《猫科动物和企鹅在窗口外看机器人吃苹果》这出戏太美,很多公司都希望能全平台同时发布新版本app,还要能复用代码以降低开发成本。这迫使一部分已熟悉某个平台的先锋们转岗到另一个平台边学习边开发。最终有少部分人在每个战场都打拼过,从而能全盘考虑以设计出良好的可复用架构。 革命总会出新知,今天已有一些开源框架能应对同时在5大平台Mac OS X、Linux、Windows、Android、iOS上开发客户端,新人们可以不再过多关心系统底层的那些事儿。不过多学点还是有很大好处的,最简单地概括就是会发现大道归一,多种编程语言、系统API、开发工具其实都是解决同一堆问题。越新的方法越方便,可是却算不上越简单。在理解这些之后,就会对编程乃至程序员职业本身有了更深层的看法。 (想到什么写什么,其实远远没总结完)

2 开发2.1 开发环境

程序员肯定喜欢集代码编辑、编译、打包等一体化的IDE。然而好的IDE都不跨平台,比起写代码,掌握所有平台的官方tool chain是一件比较无聊的事,可是又重要得必须去做。

作用/工具/平台 Windows Max OS X、iOS Android Linux 跨平台

IDE Visual Studio Xcode Eclipse / IntelliJ IDEA 无官方版 自己打造=跨平台代码编辑软件+快捷键+命令行工具

工程文件 VS、Makefile xcodeproj Java IDE的、Android.mk Makefile cmake、gyp

代码编辑 可用IDE 可用IDE 可用IDE 无主流 Vim、Emacs、Sublime Text、Eclipse

命令行编译 cl、devenv、nmake xcode-build(以前是gcc,现在是clang) ant、ndk-build gcc、make gcc、clang

调试 VS、WinDbg Xcode(GDB、LLDB) JDB、GDB GDB 无

打包 Windows Installer、第三方工具 Xcode+zip aapt dpkg、checkinstall 无

很多好用的工具是某平台特有的,可以帮助检查多平台共有的部分代码,如Linux下的valgrind帮助检查内存泄露,Xcode自带Analyze静态检测代码等。 无论是什么工具,查阅说明文档和用户手册是最基本的工作。因为信息量太大且应用场景过于局限,会难有做笔记的动力,用到什么就查什么,多查几次自然就记住了。 如果是人力资源充足,最好能有专人负责所有平台的基础设施建设,而不是一个平台一个专家。在这方面研究透彻,后面的工作会事半功倍。

另外,跨平台开发肯定会用到虚拟机(Virtual Box或VMWare)。利用磁盘共享功能,可以修改代码后立刻在多个平台编译调试。推荐以Linux为Host,因为它工具多、系统性能高,能让工作效率最大化。

2.2 编程语言

理论上说,可以用C/C++写遍全平台(有转译神器的语言就不提了)。然而除非是自虐,否则没什么理由不在Android和iOS上分别用到一些Java和Objective-C,因为那样更容易调用便利的系统API。总之,做跨平台开发是不能只懂C/C++的。 而且,一般会用到脚本做一些自动化处理,例如检查代码规范、按文件模板生成代码、按配置打包资源文件等。目前流行的是python,因为它跨平台。跨平台的另外还有perl和ruby。如果算上Cygwin的帮助,那么shell就不仅仅是*nix专用的脚本语言了。不跨平台的话,Windows是batch file,Mac是AppleScript。 如果不幸碰上客户端需要显示网页(移动端上使用WebView),还少不了要懂点HTML/CSS/JavaScript。

语言学多了,会发现有许多共通点。

编程语言的最终目标都是为了生成CPU指令,只不过是承担了越多工作的编程语言,需要程序员写的代码越少而已。形象点说就是所有语言都是汇编的子孙,基因大部分是相同的,长得胖的穿衣服少罢了。所以,随着语言越学越多,每学一种新的都会越快上手。 学多了会混乱,编程书籍或网页参考常备身边是个好办法。

2.3 操作系统

编程语言用到极致,最多也只能做纯数据运算。程序与外部交互的媒介是操作系统,所以跨平台开发还是得熟悉各个操作系统的特性。编程到了一定阶段,查系统SDK/API的用法会成为常态。最后你会发现,无非也就这几类:

使用第三方库能简化系统API和弥补不足,例如boost库能屏蔽很多系统API的差异,并有很多强大的工具。然而不能期望第三库能满足所有的需求,需要自己开发特定需要的库并不断积累,或许有一天还能贡献反哺给开源社区。 如果是做游戏客户端,以上需要关心的东西会更少,除非重新写一个游戏引擎。

为了符合平台用户体验、效能效率最优化、提升开发速度等目的,有时候我们必须使用特定操作系统的功能与界面,所以并不是对系统浅浅了解即可。根据开发的目标不同(特别是涉及硬件的),有时候还要挖掘底层API来用。

2.4 一些跨平台编程的坑

每个平台的坑都多如牛毛,是程序就有缺陷。举几个例子: Windows带来的宏,如max、AddJob,这些不能作为函数名,否则Linux编译过了Windows会不过。

size_t在printf中的表示,Linux是%zu,Windows是%lu,没有通用的。当然,可以把这些warning关掉。

在linux平台能稳定运行的代码,在windows不一定行。例如

const char* GetString() { std::string temp = “1234”; return temp.c_str();}

因为STL的实现可能不同。还有系统内存回收机制也不同。

有些库只是特定平台需要,zlib(libz)就只有Windows需要。其余系统有自带的。

还有一些不算坑,仅算差异,但为了全平台能编译得过,仍需要记住。例如DEBUG宏不是所有平台都有的,动态库的接口导出写法不同:

MY_EXPORT __declspec(dllexport)MY_EXPORT __attribute__((visibility(“default”)))#endif3 维护3.1 架构设计

把架构设计放在维护这节是故意的,因为在跨平台产品中,可维护性是一切变态需求和bug的救星,这正正体现了架构设计的价值。 设计的结果基本上都是把程序分为三大层,从低到高是:平台无关层->平台抽象层->平台相关(适配)层。

平台无关层包含数据处理和逻辑控制。数据处理是指通用数据描述(XML、JSON、Google ProtocolBuf),,持久化存储,字符编码/多语言/国际化(ICU),图片解码,音频/视频解码,资源管理,log等。逻辑控制多是业务流程的实现。

平台抽象层把平台间有差异的部分做抽象,由平台相关层实现。这层是最考验设计功底的。

贪婪是最真实的贫穷,满足是最真实的财富

跨平台客户端开发经验总结

相关文章:

你感兴趣的文章:

标签云: