同时开发Android和iOS应用是一种怎样的体验?
一个天堂,一个地狱。
一:开发环境
iOS的Xcode是垃圾中的垃圾,尤其是现在对Swift的支持。我之前用的时候,代码高亮每三次就崩溃一次。Xcode的崩溃次数肯定是Android IDE的好几倍,而且真的很卡。感觉上下拖动没有60帧。
Android之前的Eclipse也是垃圾,后来的Intelijia/Android Studio就好多了。代码太多,我干脆给他分配3G内存(我的电脑是16G 13寸rmbp),会好很多。但是自从Android全面切到Gralde之后,感觉Gradle编译真的很慢,尤其是多个模块依赖的时候,需要multidex的方法超过6k5的时候简直就是噩梦,因为打开multidex之后就不支持增量编译了。在这方面,iOS要好得多。iOS使用cocopod管理依赖,改几行代码的编译速度确实比Gradle快。
不过iOS可以用AppCode,但是这个东西跟不上Xcode的发布速度,比如iOS9,Xcode7,但是写AppCode太老了,各种语法错误可以得到新的开发版本,但是开发版本对iOS新功能的支持肯定是不完整的。
第二,开发语言
iOS的OC语法怪异繁琐,但是习惯不错。这个东西调用C/C++比安卓用的Java好多了。后来Swift改进太多,目前还不成熟,主要是Xcode太垃圾,不过现在用Swift写的iOS App越来越多了。Android版Java死了,死在1.7。不可能上1.8的Lambda,虽然有第三方库这么做。Jetbrain的Kotlin刚开始支持Android,连1.0都没有。如果想用Kotlin写Android,至少要等2、3年。
三:页面导航和保存场景
IOS用ViewController,Android用Activity,VC的push==Android的startActivity,VC的present==DialogFragment.show。
无论哪个系统都有内存不足的问题,当应用被切到后台时,Android原生支持序列化保存场景,这样app回收后就可以恢复(当然你也可以不做,比如百度地图的某个版本就是这样,每次切出来都超载)。碎片这么复杂,iOS默认不支持,需要开发者自己编写非常复杂的代码。所以你可以看到基本上没有一个iOS App在后台被破坏后还能恢复到现场。一般有复杂重载页面的iOS apps都需要使用ViewController来相互嵌入,称为ViewController容器。在Android上,是活动嵌入片段嵌入子片段。
因为VC之间不需要保存数据,直接给VC对象的某个属性赋值就可以了。Androd必须通过Intent,数据必须支持序列化。当然,如果你不想保存场景,就跟iOS一样。其实我也不知道哪个更好,因为iOS里有人抱怨iOS的做法让两个VCS夫妇太强势了。
四:App内存
iOS App启动后,差不多有1/2的系统总内存可用,但安卓和安卓的差距很大,从32mb到195mb+(2G总内存)不等,这关系到整个手机的总内存。不知道没用过3G或4G内存的安卓手机堆大小是多少?这使得Android的内存更容易出现问题。反正有一个问题就是代码写的不好,内存因为强引用而泄露。
五:UI,兼容性适配
IOS从最早的手动帧,为了适应ip4 ip5自动调整大小,到后来的AutoLayout,再到后来的Size类。但是StoryBoard的自动布局非常非常难用。稍微复杂的界面和左侧的一堆约束是不可能改变的。相比之下,现在让我吐槽,眼睛都疼了。所以很多人用第三方代码AutoLayout库,比如Masonry,但是我用起来还是觉得啰嗦。为了适应,iOS9增加了UIStackView,其实就是Android的LinearLayout。AutoLayout的另一个问题是卡,所以基本上没有人会在UITableView的单元格中使用AutoLayout,而且都是手动框架布局。
在iOS的开发过程中出现过很多争论,比如代码画图布局(要么是手动框架,要么是各种第三方布局库)或者全故事板/Xib,这两种都很恶心。代码绘图,VC是布局和业务,后者不是人能用的。StobyBoard/Xib根本不可读,这对版本管理来说是个灾难。而且我个人很怀疑Xcode能否打开复杂的故事板,让它不崩溃。
Android一般用XML画布局和代码做生意,相对好很多。XML非常容易读写。ListView写一个单元格的速度比UITableView快很多。iOS需要你自己计算身高。当然,你不必这样。就像我上面说的,如果你不怕卡,但是,安卓兼容的麻烦就是Rom兼容,尤其是国产厂商。因为对框架层改动太多,容易踩坑。
对于系统Api和系统版本更新的坑,我的印象是iOS和Android都不会缺,逃不掉。我诚实地接受我的命运,并找到解决办法。
六:多线程
iOS的GCD操作与Java的Executor多线程框架。就客户端开发而言,我觉得两者都没有什么麻烦和困难,都能满足需求。当然,可能是我太肤浅了。
七:存储
iOS虽然有CoreData,但是没人用。大家都喜欢SQLite。Androd官方没有ORM方案。老实说,SQLite,第三方的ORM,反正我对iOS分配给App的几个文件夹感到愧疚。如果在不该写的文件夹里写,比如会被iCloud备份的文件夹,会被AppStore拒绝。但是安卓很随意,整个SD卡都可以读写,某个版本的安卓禁止写第二个存储空间(大多是SD卡),后来我记得又改回来了。
八:动画
iOS的RunLoop是Android的Handler/Looper/MessageQueue。IOS有多种模式的RunLoop,可以在滚动时禁止其他UI消息,很像MessageQueue。Android上的IdleHandler。因为iOS要和OS X***,共享代码,是分屏显示和事件处理(手机触摸屏,电脑是鼠标键盘),所以有CALayer和UIView。因为Android没有历史包袱,所以由View自己处理。IOS动画可以直接用CALayer操作,Android一般用Animator操作View。但是由于版本的兼容性,很多人还是用2.x动画做安卓动画,这就渣多了。Animator的一个优点就是可以随时间随意改变属性。我记得脸书给iOS的Pop也是这样,否则你就得自己用了。
CADisplayLink封装。
TimingFunction在iOS上负责动画过程中的速度,而Android是插值器贝塞尔曲线UIBezier对应的路径。
view controller cut scene UIViewControllerTransitioning对应的是Android5的ActivityTransition,但是跟不上一般的Android手机版本。。。。很少有人用ActivityTransition。Androd没有iOS的UIKit动态库,只能自己写一些特效。
九:在架子上
我拿国内的情况举例。如果你有一个新的应用程序,你需要一个月的时间来准备把它放到AppStore上。苹果大叔每周审核一次你的app。如果有一项失败,请再等一周。评论只会给你截图和说明。可以改正,然后下周又有新的问题,这样来回四次大概要一个月。
国内没有Google Play,要去小米商店、豌豆荚、App Store、4天,比苹果的轻松很多,但是渠道很多,比较烦。一般需要改变Gradle脚本来打包不同渠道的包,来确定对应的应用市场真正分发了多少,这些都和钱有关。
十:感觉写iOS被苹果操,写安卓被手机厂商操。