首页 > 知乎精选 > 移动互联网 > Web程序员在转向移动开发过程中有哪些经验和教训值得大家借鉴?
2015
10-22

Web程序员在转向移动开发过程中有哪些经验和教训值得大家借鉴?

本文素材采自覃超,曾经沧海难为水,Facebook工程师

说“转型”可能我还不够资格,因为我从工作开始就直接在做mobile,只是之前在大学里面搞过一些程序竞赛和TopCoder的组件开发在桌面电脑上面,所以从一开始我就是还没完全定型的程序员,基本上什么东西都需要从头学习。第一次真正开发mobile程序还是在CMU读master的时候,那时做毕业论文,研究Android系统的安全性,于是第一次装了Android的文档和自己照着样例写了一个,感觉还挺不错(其实就是写Java)再后来就是进入Facebook后,从Boot camp毕业后就进入Mobile team,当时公司里面大部分人还是搞PHP的,但是公司鼓励大家做Mobile开发,说是以后的方向,于是我从一入职就开始了全面的Mobile开发。

个人的经验如下:

技术方面: 我个人感觉Mobile上面更加注重程序的效率,程序要简洁,速度快,同时复杂度要尽量低。另外就是在写程序时具体要注意的事项,由于Mobile的处理能力不及桌面电脑,所以要格外注意将非UI相关的操作放入到worker thread。

相比开发桌面程序或者web app,亦或者是现在的iOS或者Android开发,MVC模式已经深入人心,它的本质就是把代码按照其做的事情分类,坐不同工作的代码在不同的模块里; Thread分类和它也类似。刚开始进行Android Facebook和Facebook Messenger开发的时候,我们的Tech Lead — Jon Perlow 就在code review中不断指出我的很多操作还是像桌面程序一样放在主线程中,而Android下主线程即 UI thread,这样就很可能降低程序的流畅性。而且很多时候,也其中蕴藏着一定的平衡和折中。因为移入worker thread后,程序会出现很多async method call和callback function/class, 这样对代码的可读性和以后的维护都是挑战,同时线程的切换和对于共享资源的同步也是会带来性能的损失,所以在写的时候要具体问题具体分析。

比如说大规模I/O操作和上百万次的循环,自然不用说;但是在很多情况下,就没有如此明显吧,比如说判断一个文件是否存在, new File(getDucumentFolder + “/xyz”).exist() 也算I/O操作,那到底要不要移入worker thread呢?另外很多时候,你最开始的函数里面,可能操作非常简单,就直接在Main thread里就可,可是后来其他人在refactor的时候,将这些操作放开到好几个function里面去做,然后在以后的版本中,由于加入了新的feature,每个function里面都比之前要做更多操作的时候,就逐渐逐渐地让Main thread的负担加重,搞到最后给用户的感觉就是这个App功能是变多了,但也越来越笨重,越来越容易crash。所以说,不要在UI thread里做事这点,想必只要智商上80的人都懂,但是真正要执行的时候并不是如此得显而易见,而同时,公司里的项目都是多人作战,每个人一般都着眼于自己做的那一块,这样很容易就造成最后UI Thread里面的工作量远比开始设计的要多。

现在主要的手机平台就是Android和iOS,所以建议两个都要去了解,然后专注于一个平台。如果Android的话,除了看Google官网外(developer.android.com/t ), 很多时候当你具体要调用一个API,但是文档上面有疑惑的时候,最好的办法肯定还是能回到代码里面去确认。

通篇浏览Android的代码肯定不现实,我个人(也是公司里面)觉得最有用的办法就是安装plugin:chrome.google.com/webst ,然后搜到文档后,页面上直接有一个链接 (View Source)来方便查看代码。回到上面那个线程切换的问题,Android有三种办法:AsyncTask, Handler, Executor. 在代码里面(还有Stack Overflow上面的讨论),AsyncTask是最差的办法,它属于Google自己加入的一个Hack,大量在自己的Android App里面使用会发生阻碍程序性能的奇怪问题(因为你对它的worker thread pool没有任何控制);Handler比较简单,适合将单个任务快速丢到另外的thread里面执行,但是从源代码就可以看出Handler本质上也是在调用executor。

最后就是Executor自己了,它的坏处是比较复杂,不注意容易出错,但是好处就是性能好,而且功能强大。可以自己定义queue的属性,指定thread pool的大小,和筛选并处理
或者取消还没被执行的任务等等。所以只有在源代码里面去确认后,才会对每个模块在使用有直接和全面的了解。这样就能理解为什么公司里面Android的编程规范里面来一句“Don’t use AsyncTask”是什么意思。(很多人问我为什么不能用AsyncTask,其实在Android API的document里面就有developer.android.com/r , 看它自己的注释。另外还有一个blog:commonsware.com/blog/20 ) 多提一句,如果两个平台都做的话,还可以比较在iOS下面对线程切换的做法,iOS上鼓励的是使用GCD (grand-central-dispatch)。他们各有自己的特点,但是个人认为iOS的GCD更加简单,也更加符合人的思维。

另外就是UI方面,我做过Facebook Messenger for iOS的UI,但是设计毕竟不是来自本人之手,所以只当是自己的拙见。个人觉得UI越简洁越好,另外就是在设计UI的不要进入误区:认为app的Android版本和iPhone版本UI要一模一样。还有一些自己在做UI的时候,designer给我的细节性的建议:“比如text一般加一个pixel的半透明的shadow“, 按钮(透明)的实际大小一般比贴图再大一些,这样更方便用户触摸。

上面都是在讨论的时候,即兴想到的东西,没有太多整理。不过这两年在FB的打磨让我觉得最重要的不是你的技术多牛,写代码写得多快,而是适应力要强,能够也愿意push自己去转型。我见过不少人,之前对某一技术或者某一领域炉火纯青了,就一直想呆在自己的领域里,说是精益求精也好,说是吃老本也好,更有甚者就是想用老本的技术来用于新的领域。Mobile上面跑HTML5的离线App我觉得就是其中一个,具体细节我整理一下,放到另外一个问题里。

最后编辑:
作者:管理员
呃...怎么介绍呢?就是个管理员吧~
捐 赠如果您觉得这篇文章有用处,请支持作者!鼓励作者写出更好更多的文章!