一饭弓、前言
Android和iOS是移動端兩大平臺双饥,Android開源、易上手弟断、成本低受咏花、跨平臺;iOS作為蘋果的封閉系統(tǒng)阀趴,簡單昏翰、流暢、高效刘急。本人從iOS轉(zhuǎn)Android棚菊,結(jié)合一些資料和自己的理解進行一些總結(jié)。
二叔汁、基本對比
1统求、Android和iOS簡介
Android是一種基于Linux的自由及開放源代碼的操作系統(tǒng)检碗,由Google公司和開放手機聯(lián)盟領(lǐng)導(dǎo)及開發(fā),主要使用于移動設(shè)備球订,如智能手機后裸、平板電腦、谷歌眼鏡等冒滩。
iOS是由蘋果公司開發(fā)的移動操作系統(tǒng)?微驶。設(shè)計給iPhone、iPod touch开睡、iPad因苹、AppleWatch以及Apple TV等產(chǎn)品上。iOS與蘋果的Mac OS X操作系統(tǒng)一樣篇恒,屬于類Unix的商業(yè)操作系統(tǒng)扶檐。
2、開發(fā)語言
2.1胁艰、Android常用的開發(fā)語言是Java款筑,Java具有簡單性、面向?qū)ο蟆?a target="_blank" rel="nofollow">分布式腾么、健壯性奈梳、安全性、平臺獨立與可移植性解虱、多線程攘须、動態(tài)性等特點。Java可以編寫桌面應(yīng)用程序殴泰、Web應(yīng)用程序于宙、分布式系統(tǒng)和嵌入式系統(tǒng)應(yīng)用程序等。
Kotlin 是一個用于現(xiàn)代多平臺應(yīng)用的靜態(tài)編程語言悍汛,Google IO 2017宣布了 Kotlin 會成為 Android 官方開發(fā)語言捞魁。
2.2、iOS常用開發(fā)語言是Object-C离咐,Objective-C在C的基礎(chǔ)上署驻,加入面向?qū)ο?/a>特性而成的編程語言。
Swift是蘋果公司在2014上發(fā)布的全新開發(fā)語言健霹。Swift內(nèi)在依然是Object-C旺上,但Swift大大地降低了開發(fā)門檻。
常規(guī)的C和C++亦可用于iOS開發(fā)糖埋。但使用C和C++做ios開發(fā)的人越來也少宣吱。
3、開發(fā)環(huán)境和工具
Android常用Android Studio和Eclipse瞳别,可以在Windows征候、Mac杭攻、Linux等多平臺安裝并開發(fā)。
iOS使用XCode開發(fā)疤坝,只在Mac系統(tǒng)平臺下使用兆解。雖然可以在其他平臺使用虛擬機開發(fā),但其難度和操作大跑揉。
三锅睛、技術(shù)對比
1、UI界面
1.1历谍、創(chuàng)建和布局
Android有兩種方式繪制View现拒,一是使用xml文件,你可以在xml文件中用代碼聲明你的界面望侈,也可以直接在可視化的界面上拖拽印蔬,控件可以通過R文件生成唯一對應(yīng)的id,在Java 代碼中就能通過id來找到控件并處理邏輯脱衙。二是在Java中使用代碼繪制View和布局侥猬。
iOS提供了三種方式來布局和繪制View,一是使用storyboard捐韩,二是使用xib文件(nib)退唠,三是純代碼布局。前兩種方式是不需要代碼的奥帘,將View和Controller剝離開來,而且不需要在類似xml的源碼中添加代碼仪召,只需要在視圖上鼠標操作就可以寨蹋。第三種是使用代碼來繪制View與布局。使用代碼布局更自由扔茅,而且能達到一切想要的效果已旧。
二者都有可視化布局方式,能夠拖拽設(shè)置屬性完成界面的簡單布局召娜,Android通過修改對應(yīng)的xml代碼修改屬性运褪,而iOS直接通過屬性設(shè)置完成。二者都有相對布局玖瘸、約束布局和絕對布局秸讹,Android還有線性布局、框架布局雅倒、網(wǎng)格布局等方式璃诀。特別注意的是,iOS沒有Android中View的長寬屬性wrap_content蔑匣,這使得在動態(tài)寬高變化的時候劣欢,需要自己計算棕诵。
1.2、控件
兩個平臺提供的官方UI控件及屬性基本類似凿将,基本能滿足簡單APP的搭建校套。在Android中基本都有和iOS對應(yīng)的控件,Android還提供了更多的常用控件牧抵,如選框笛匙、菜單、吐司等灭忠,不同的是他們的API不同膳算,使用方法不同,某些外觀能明顯看得出蘋果的設(shè)計風格弛作。iOS的大多數(shù)控件都比Android高度封裝化涕蜂,比如創(chuàng)建一個需要層次化流程的界面,iOS使用UITarBarController+UINavigationController非常簡單方便創(chuàng)建映琳,雖然Android有TabHost机隙,但是想要創(chuàng)建與iOS的搭配效果,需要更多的自定義代碼萨西。
Android所有的UI界面都是由View及其派生類組合而成有鹿,開發(fā)過程中不會直接使用View,而是使用其派生類和自定義View谎脯;iOS中UIView是大部分UI控件的基類葱跋,開發(fā)的時候經(jīng)常直接或自定義使用UIView。
高級控件的實現(xiàn)有較大的不同源梭,如ListView和UITableView的表格視圖娱俺,Android的ListView使用了Adapter適配器來處理顯示,而iOS使用dataSource和delegate代理方法代替Adapter的作用废麻。
Android還有Fragment(碎片)荠卷,表示Activity中的某部分界面或者行為,可以自己加載布局文件烛愧,必須與Activity配合使用油宜。Fragment有自己的生命周期,依賴于Activity怜姿,使用Fragment能夠更加動態(tài)和靈活設(shè)計UI慎冤。
2、控制器
控制器controller是控制UI和處理邏輯沧卢,iOS中是通過UIController管理粪薛,對應(yīng)Android的是Activity,二者作用相當搏恤,其生命周期也相似违寿。
Android的Activity是由Activity棧進管理湃交,當來到一個新的Activity后,此Activity將被加入到Activity棧頂藤巢,之前的Activity位于此Activity底部搞莺。可以設(shè)置Activity的taskAffinity和launchMode掂咒,以改變Activity入棧的形式才沧。
iOS沒有UIViewController啟動模式,但提供了三總對視圖的管理方式:
a绍刮、UITabBarController:以平行的方式管理視圖温圆,每個加入到UITabBarController的視圖都會進行初始化即使當前不顯示在界面上,相對比較占用內(nèi)存孩革;
b岁歉、UINavigationController:以棧的方式管理視圖,各個視圖的切換就是壓棧和出棧操作膝蜈,出棧后的視圖會立即銷毀锅移;
c、UIModalController:以模態(tài)窗口的形式管理視圖饱搏,當前視圖關(guān)閉前其它視圖上的內(nèi)容無法操作非剃。
3、數(shù)據(jù)存儲
Android存儲數(shù)據(jù)有以下幾種方式:
a推沸、Shared Preferences:是用來存儲一些Key/Value類似的成對的基本數(shù)據(jù)類型备绽,保存用戶的簡單數(shù)據(jù)。
b鬓催、內(nèi)部存儲與外部存儲:內(nèi)部存儲指手機內(nèi)置存儲空間肺素,外部存儲指SD卡,通過文件或文件夾操作存儲數(shù)據(jù)深浮。
c压怠、Sqlite3:開源嵌入式關(guān)系型數(shù)據(jù)庫眠冈,可移植性好飞苇、易使用、內(nèi)存開銷小蜗顽。
iOS是沙盒存儲布卡,數(shù)據(jù)都在APP的目錄下,存儲方式有以下幾種:
a雇盖、NSUserDefaults:原理同Shared Preferences忿等,用來保存應(yīng)用程序設(shè)置和屬性、用戶保存的數(shù)據(jù)崔挖。
b贸街、NSKeyedArchiver:歸檔采用歸檔的形式來保存數(shù)據(jù)庵寞,該數(shù)據(jù)對象需要遵守NSCoding協(xié)議。對象對應(yīng)的類必須提供encodeWithCoder和initWithCoder方法薛匪,對對象進行編碼和解碼捐川。
c、屬性列表:保存數(shù)據(jù)到沙盒文件目錄逸尖。
d古沥、Sqlite3:同Android。
e娇跟、Core Data:是對SQLite的封裝岩齿,提供了更高級的持久化方式。
4苞俘、多線程
在主線程進行耗時操作會帶來非常差的體驗感盹沈,iOS和Android都需要通過多線程處理。
iOS有以下幾種方式:
NSThread這套方案是經(jīng)過蘋果封裝后的苗胀,并且完全面向?qū)ο蟮慕笾睢K阅憧梢灾苯硬倏鼐€程對象,非常直觀和方便基协。NSThread輕量級歌亲,使用簡單需要自己管理線程的生命周期、線程同步澜驮、加鎖陷揪、睡眠以及喚醒等。線程同步對數(shù)據(jù)的加鎖會有一定的系統(tǒng)開銷杂穷。
GCD是蘋果為多核的并行運算提出的解決方案悍缠,會自動合理地利用更多的CPU內(nèi)核,最重要的是它會自動管理線程的生命周期耐量,完全不需要我們管理飞蚓,我們只需要告訴干什么就行。它使用C語言廊蜒,由于使用了Block趴拧,使得使用起來更加方便,而且靈活山叮。很多App都會使用這套方案著榴。它有兩個概念:任務(wù)和隊列。任務(wù)分同步和異步屁倔。同步任務(wù)會在當前線程執(zhí)行脑又,不會另開線程,會阻塞當前線程,直到block中的任務(wù)執(zhí)行完畢(block在當前線程中執(zhí)行)问麸。異步任務(wù)會另開線程往衷,在別的線程執(zhí)行。當前線程會直接往下執(zhí)行严卖,不會阻塞當前線程炼绘。(block在新線程中執(zhí)行)。隊列用于存放任務(wù)妄田。一共有兩種隊列俺亮,串行隊列一次只執(zhí)行一個線程,F(xiàn)IFO疟呐。并行隊列:一次可以執(zhí)行多個線程脚曾。
NSOperation和NSOperationQueue。NSOperation 是蘋果公司對 GCD的封裝启具,完全面向?qū)ο蟊炯ィ允褂闷饋砀美斫狻SOperation 和NSOperationQueue分別對應(yīng)GCD的任務(wù)和隊列鲁冯,它的用法和GCD很像拷沸。與GCD不同的是它的任務(wù)能被取消,隊列可以暫停薯演、恢復(fù)撞芍,NSOperation還可以被子類化。
Android有以下幾種方式:
Runnable/Thread 是Java中的跨扮,可以擴展繼承Thread類來創(chuàng)建一個線程序无,也可以繼承Runnable接口來創(chuàng)建一個線程,再結(jié)合Android中的Handler即可以在子線程中更新主線程UI了衡创。
ExecutorServie線程池也是Java中的概念帝嗡。它的作用是通過重復(fù)利用已經(jīng)創(chuàng)建的線程來避免創(chuàng)建和銷毀線程造成的消耗,同時提高響應(yīng)速度和線程的可管理性璃氢。當Android中有一些不需要更新UI的操作哟玷,通常采用這個方法。
IntentService它是繼承于Service并處理異步請求的一個類一也,在IntentService內(nèi)有一個工作線程來處理耗時操作巢寡,啟動IntentService的方式和啟動傳統(tǒng)Service一樣。當任務(wù)執(zhí)行完后塘秦,IntentService會自動停止讼渊,而不需要我們?nèi)ナ謩涌刂贫础A硗庾鹛蓿梢詥覫ntentService多次,而每一個耗時操作會以工作隊列的方式在IntentService的onHandleIntent回調(diào)方法中執(zhí)行菱皆。它處理業(yè)務(wù)流程非常方便须误。
AsyncTask是Android提供的輕量級的異步類挨稿,在類中實現(xiàn)異步操作,并提供接口反饋當前異步執(zhí)行的程度(可以通過接口實現(xiàn)UI進度更新),最后反饋執(zhí)行的結(jié)果給UI主線程京痢。它最重要的兩個方法奶甘,一個是doInBackground(params):處理耗時事務(wù),并把結(jié)果返回祭椰。一個是onPostExecute(result)可以使用在doInBackground得到的結(jié)果處理操作UI臭家。很多人都推薦使用它處理需要更新UI的操作。
Service作為四大組件之一方淤,用于在后臺管理和處理一些耗時的邏輯線程或者某些需要長期運行的線程钉赁。這里要說明的是Service不是運行在后臺線程的,它仍然是運行在UI主線程携茂,所以如果要用它處理耗時任務(wù)你踩,你還是得在其中創(chuàng)建新線程。它的作用是能在后臺對線程進行良好的管理讳苦,對外提供AIDL接口带膜。Service的一個經(jīng)常的應(yīng)用是保持著心跳連接。
5鸳谜、進程間通信
Android的進程間通信方式有很多膝藕,如ContentProvider,Activity咐扭,廣播和AIDL等束莫,不過這些方式的本質(zhì)都是binder。
Content Provider是Android四大組件之一草描,它提供了一種在多個應(yīng)用程序之間數(shù)據(jù)共享的方式览绿。應(yīng)用程序可以利用Content Provider完成查詢數(shù)據(jù),修改數(shù)據(jù)穗慕,添加數(shù)據(jù)饿敲,刪除數(shù)據(jù)。需要創(chuàng)建ContentResolver對象與ContentProvider進行交互逛绵,通過指定的URI確定要訪問的ContentProvider數(shù)據(jù)集怀各。
Activity很好理解,就是可以在自己的App跳轉(zhuǎn)到別的程序的界面术浪。但跨進程訪問并不需要指定Context對象和Activity的Class對象瓢对,而需要指定的是要訪問的Activity所對應(yīng)的Action,有些Activity還需要指定一個Uri胰苏。
廣播硕蛹,前面說過廣播可以在系統(tǒng)級,所以廣播能跨進程通信,一些系統(tǒng)通知經(jīng)常會用到它法焰,例如通知時區(qū)改變秧荆、電池電量低、拍攝了一張照片或者用戶改變了語言選項等等埃仪。
AIDL實際上是一種接口定義語言乙濒。通過這種語言定義接口后,Eclipse插件會自動生成相應(yīng)的Java代碼接口代碼卵蛉。它需要創(chuàng)建AIDL文件和一個Service來配合使用颁股。
Binder。這是最底層的進程通信了傻丝。主要是有ServiceManager這樣一個東西來控制豌蟋,所有的服務(wù)都要通過它來注冊,提供它的binder地址桑滩,其它程序如果需要哪種服務(wù)就向它申請梧疲,在ServiceManager獲得了對端地址之后,你們兩就通過Binder驅(qū)動進行通信了运准。
對于iOS來說幌氮,為了避免數(shù)據(jù)沖突和更好的提供更好的安全機制,iOS提供了沙盒機制胁澳。盡管如此该互,iOS還是提供了若干今晨間通信機制,如URL Scheme韭畸、剪切版宇智、CoreCFMessagePort和CFNotificationCenter等等。
URL Schema就是iOS內(nèi)的應(yīng)用調(diào)用協(xié)議胰丁,應(yīng)用A可以聲明自定義的調(diào)用協(xié)議随橘,就如http/https那樣,當另一個應(yīng)用B打算在應(yīng)用內(nèi)打開應(yīng)用A時锦庸,可以打開使用A自定義的協(xié)議開頭的URL來打開A机蔗,除了協(xié)議頭,URL中還可以附加其它參數(shù)甘萧。
剪切版很好理解萝嘁,用戶可以跨應(yīng)用拷貝了一段文字,圖片扬卷,文檔等牙言。在代碼中對應(yīng)的類是:UIPasteboard。
CFMessagePort怪得,通過mach port實現(xiàn)的咱枉。它需要消息接收者和消息發(fā)送者卑硫。消息發(fā)送者需要通過CFMessagePortCreateLocal、CFMessagePortCreateRunLoopSource庞钢、CFRunLoopAddSource來注冊監(jiān)聽,并自己實現(xiàn)回調(diào)方法因谎。發(fā)送者通過CFMessagePortCreateRemote生成一個Remote的CFMessagePortRef基括,并通過CFMessagePortSendRequest發(fā)送數(shù)據(jù)。遺憾的是iOS7以后不能用這個方法了财岔。
CFNotificationCenter通知可以是系統(tǒng)級別的风皿,它的原理和NSNotificationCenter一樣。CFNotificationCenter只提供類方法CFNotificationCenterGetDistributedCenter獲取通知發(fā)布中心匠璧,需要通過CFNotificationCenterAddObserver添加所要指定監(jiān)聽消息名和觀察者到通知發(fā)布中心桐款,當消息接收到的時候函數(shù)指針指向的函數(shù)將被執(zhí)行一次。發(fā)送著只需要通過CFNotificationCenterPostNotification發(fā)送消息名夷恍、對象還有user info就可以了魔眨。
6、消息處理機制
Android里的消息處理機制:消息是存放在一個消息隊列中酿雪,應(yīng)用程序的主線程圍繞這個消息隊列進入一個無限循環(huán)的遏暴,直到應(yīng)用程序退出。Looper就是消息處理機制的關(guān)鍵指黎,每一個線程都有唯一的Looper朋凉,主線程中的Looper默認開啟。如果隊列中有消息醋安,應(yīng)用程序的主線程就會把它取出來杂彭,并分發(fā)給相應(yīng)的Handler進行處理;如果隊列中沒有消息吓揪,應(yīng)用程序的主線程就會進入空閑等待狀態(tài)亲怠,等待下一個消息的到來。
這里要注意的是其它線程不是默認開啟的柠辞。但是如果你需要線程在處理完一些事情后赁炎,不要自己停止,那么就需要使用Looper钾腺。Looper由四個部分組成:
Message:消息徙垫,其中包含了消息ID,消息處理對象以及處理的數(shù)據(jù)等放棒,由MessageQueue統(tǒng)一列隊姻报,終由Handler處理。
Handler:處理者间螟,負責Message的發(fā)送及處理吴旋。使用Handler時损肛,需要實現(xiàn)handleMessage(Message msg)方法來對特定的Message進行處理,例如更新UI等荣瑟。
MessageQueue:消息隊列治拿,用來存放Handler發(fā)送過來的消息,并按照FIFO規(guī)則執(zhí)行笆焰。當然劫谅,存放Message并非實際意義的保存,而是將Message以鏈表的方式串聯(lián)起來的嚷掠,等待Looper的抽取捏检。
Looper:消息泵,不斷地從MessageQueue中抽取Message執(zhí)行不皆。因此贯城,一個MessageQueue需要一個Looper。
iOS也有類似的東西名叫runloop霹娄,它的作用其實和looper 是一樣能犯,每個線程只有一個Runloop,在主線程中默認啟動犬耻,一直循環(huán)接收消息悲雳。當你需要在其它線程干一些其它事時也可以自己啟動。不能自己創(chuàng)建RunLoop香追,CFRunLoopGetMain和 CFRunLoopGetCurrent可以獲得Runloop合瓢。RunLoop負責處理兩種消息事件,輸入源事件和計時器事件透典。它具體的作用是維護線程的生命周期晴楔,讓線程不自動退出;創(chuàng)建常駐線程峭咒,執(zhí)行一些會一直存在的任務(wù)税弃。?
四、總結(jié)
Android和iOS作為移動端的OS凑队,市場占有率超90%则果。一個屬于Google一個屬于Apple,雖然是兩個公司漩氨,但是很多的風格元素和技術(shù)特點也越來越相似西壮。從宏觀上講,iOS和Android最大的不同應(yīng)該是一個底層是Linux系統(tǒng)叫惊,一個是蘋果特有的封裝系統(tǒng)款青。蘋果特有的系統(tǒng)能夠保證在相同配置下,在顯示霍狰、動畫和運行效率上都優(yōu)于Android系統(tǒng)抡草。還有一個點是饰及,一個是開源另一個閉源,開源可以擁有更多的自由和創(chuàng)造力康震,閉源提供標準化規(guī)則和建議保證質(zhì)量燎含。總之腿短,未來兩個平臺二分天下或者一方獨領(lǐng)屏箍,我們都充滿了期待。
參考鏈接
https://blog.csdn.net/xoperxoper/article/details/52282540
http://www.reibang.com/p/f56c0a921c32
http://www.reibang.com/p/e162b76e3e6f
http://www.reibang.com/p/042f0660510a