新聞中心
前言
Android原生開發(fā)的生態(tài)一直在不斷地發(fā)展變化,過去5年從事android開發(fā)的經(jīng)歷讓我深刻的體會(huì)到了這一點(diǎn)。每隔2到3年,谷歌就會(huì)發(fā)布一些的新的開發(fā)指導(dǎo)建議、libraries、frameworks,我花了很多時(shí)間來認(rèn)真審查這些變化并從中找出可能存在的問題。我相信許多Android開發(fā)者都有我這樣類似的經(jīng)歷。

然而,2019年絕對(duì)是Android原生開發(fā)生態(tài)發(fā)生劇變的一年。在這一年里,Android sdk添加了許多新的內(nèi)容、重寫和移除了一些舊的內(nèi)容,官方的開發(fā)者指南也進(jìn)行了大幅度的更新。想要對(duì)Android開發(fā)有一種完整而又詳細(xì)的認(rèn)識(shí)實(shí)在是太難了。
于是我寫下了這篇文章,我試圖去總結(jié)Android生態(tài)系統(tǒng)中所發(fā)生的事情,并對(duì)原生開發(fā)的未來做出一些預(yù)測(cè)。接下來我會(huì)把我的觀點(diǎn)分成不同的章節(jié)來進(jìn)行具體的闡述,文章的最后我會(huì)分享一些極具爭(zhēng)議的觀點(diǎn)。
我希望這篇文章會(huì)對(duì)你們有所幫助,但是請(qǐng)記住,文章中肯定遺漏了許多重要的內(nèi)容,而且其中的許多觀點(diǎn)都是我個(gè)人的偏見。
AndroidX
AndroidX的預(yù)覽版是在一年半前發(fā)布的。大約一年前它變得穩(wěn)定了,與此同時(shí)Google也停止了對(duì)舊版Support Library的進(jìn)一步開發(fā)。當(dāng)我寫下這句話的那一刻,我想起了我之前在StackOverflow上提出的一個(gè)問題:Why does AOSP add new APIs to support libraries without adding them to SDK?(https://stackoverflow.com/questions/29197821/why-does-aosp-add-new-apis-to-support-libraries-without-adding-them-to-sdk),當(dāng)時(shí)我是一個(gè)android開發(fā)新手,我想知道Support Library背后的動(dòng)機(jī),Googl為什么不直接把Support Library放到android sdk里呢?
不過使用“穩(wěn)定”一詞來描述AndroidX似乎有點(diǎn)諷刺,因?yàn)殛P(guān)于AndroidX的任何信息似乎都不是穩(wěn)定的。 Google不斷的在往AndroidX里添加新的庫和框架。 命名空間和許多舊的API(目前還不到一年)正在以非??斓乃俣劝l(fā)展。
到目前為止,我已經(jīng)將我的兩個(gè)應(yīng)用遷移到了AndroidX。 一切都很順利,但我也不覺得有多驚喜。 Jetifier是一種將Support Library上的依賴項(xiàng)重定向到其AndroidX對(duì)等項(xiàng)的工具,轉(zhuǎn)換效果令人驚訝。 但是即使應(yīng)用程序不大,也并不是“一鍵式遷移”。
我還參與了一個(gè)尚未遷移到AndroidX的項(xiàng)目,沒有任何問題。在某些情況下,似乎我完全不需要AndroidX。
總而言之,我想說的是:如果是開啟新的Android項(xiàng)目,那么肯定是應(yīng)該使用AndroidX;對(duì)于現(xiàn)有的項(xiàng)目,我也建議您做好遷移到AndroidX的計(jì)劃,即使您現(xiàn)在看不到明顯的好處。 無論如何,您很可能都需要遷移,因此最好按自己的計(jì)劃進(jìn)行遷移,而不是以后當(dāng)你需要一些新的AndroidX庫時(shí)進(jìn)行緊急的遷移
Jetpack
在討論完AndroidX之后,就不得不提到Jetpack了。 據(jù)我所知,Jetpack最初只是“architecture components”的工具集合,但是后來擴(kuò)展為包含了AndroidX的大多數(shù)(甚至所有)API的工具集合。 因此,到目前為止,我還沒有看到AndroidX和Jetpack之間有任何有意義的區(qū)別,市場(chǎng)營(yíng)銷和公關(guān)宣傳除外。
當(dāng)您訪問Jetpack(https://developer.android.com/jetpack)的官方網(wǎng)站時(shí),它看起來不像是技術(shù)文檔,更像是早期SaaS初創(chuàng)公司的主頁。
看看這些“感言”:
再看看下面這些app:
如果Jetpack申請(qǐng)2020年獨(dú)立IPO,我不會(huì)感到驚訝,因?yàn)樗麄兪侨绱说膶W⒂跔I(yíng)銷和公關(guān)。
不過說真的,這種向自己的生態(tài)系統(tǒng)中的開發(fā)人員“銷售”api的做法存在一些深層次的問題。比如,為什么有人真的想在搜索中宣傳ViewModel?
總而言之,由于Jetpack的大部分內(nèi)容都是來源于AndroidX,所以我之前寫的有關(guān)AndroidX的內(nèi)容在很大程度上也適用于Jetpack。
下面,我將分別討論其中一些具體的API。
Background Work
當(dāng)應(yīng)用程序不在前臺(tái)時(shí)讓應(yīng)用也能執(zhí)行操作是Android開發(fā)中最常見的場(chǎng)景之一。 在引入doze模式、SyncAdapter、GCMNetworkManager、FirebaseJobDispatcher、JobScheduler以及最近的WorkManager之前,您可以通過啟動(dòng)服務(wù)(而不是綁定服務(wù))來實(shí)現(xiàn)。 這些都是Google自己的API,不過也有很多第三方解決方案,比如Android-Job。
但是,Google最近宣布,他們將通過WorkManager API來統(tǒng)一后臺(tái)任務(wù)的調(diào)度(https://android-developers.googleblog.com/2019/11/unifying-background-task-scheduling-on.html)。聽起來很不錯(cuò),但是由于某種原因,當(dāng)我聽到這樣的聲音時(shí),我總有種似曾相識(shí)的感覺……
無論最終能否統(tǒng)一,WorkManager都無法解決在執(zhí)行后臺(tái)任務(wù)過程中存在的一個(gè)最嚴(yán)重的問題:可靠性。我在這里不做解釋,但是請(qǐng)記住,如果您需要在應(yīng)用程序中執(zhí)行后臺(tái)任務(wù),請(qǐng)先閱讀dontkillmyapp.com(https://dontkillmyapp.com)上的所有信息。此外,請(qǐng)?jiān)贕oogle的issue tracker中閱讀并加注星標(biāo)。
Android系統(tǒng)的后臺(tái)任務(wù)執(zhí)行與調(diào)度是一團(tuán)糟,碎片化使得它非常細(xì)微且不可靠。
過去,我一直主張盡可能的將數(shù)據(jù)同步等類似的工作放在后臺(tái)來執(zhí)行,我可能是SyncAdapter的最后一批粉絲。 但是今天,鑒于可靠性問題,我主張相反的做法:盡可能避免在后臺(tái)執(zhí)行操作。 如果您的PM堅(jiān)持使用此功能,請(qǐng)向他們展示以上鏈接,并向他們解釋,后臺(tái)任務(wù)需要花費(fèi)數(shù)百小時(shí)的時(shí)間來實(shí)現(xiàn),而且?guī)淼穆闊┒嘤谑找妗?/p>
有些時(shí)候執(zhí)行后臺(tái)任務(wù)是不可避免的,但是在大多數(shù)情況下,您可以不這樣做。即使以給用戶帶來一些不便為代價(jià),它也可能是最佳選擇。
Databases
毫無疑問,Room在眾多SQLite的ORM框架中占據(jù)著主導(dǎo)地位。從2.2.0開始,Room支持增量注解處理。不過請(qǐng)記住,您的應(yīng)用架構(gòu)不應(yīng)過于關(guān)心使用了哪種ORM框架。因此,作為architecture components的一員,Room只是市場(chǎng)術(shù)語,而不是技術(shù)角色。
Android開發(fā)中ORM框架的主要競(jìng)爭(zhēng)者是SQLDelight。 這個(gè)庫比Room還要老,但是據(jù)我了解,在過去的一年左右的時(shí)間里,它已經(jīng)被重寫了很多。 不幸的是,它現(xiàn)在只針對(duì)Kotlin。 另一方面,SQLDelight支持Kotlin跨平臺(tái)。 因此,隨著Kotlin使用率的增加,我預(yù)計(jì)SQLDelight的使用率也會(huì)隨之增加。
順便說一下,AndroidX中有對(duì)原生SQLite的使用說明,我還不知道該怎么使用。但是如果您想在應(yīng)用中使用原生SQLite,那么你或許需要去認(rèn)真的研究下這個(gè)主題。
此外還有許多針對(duì)Android的非關(guān)系型的數(shù)據(jù)庫,例如Realm,Parse,F(xiàn)irebase,ObjectBox等(其中有些仍在使用SQLite)。如果我沒記錯(cuò)的話,它們中的大多數(shù)(甚至全部)都具有自動(dòng)數(shù)據(jù)同步功能。 一段時(shí)間以來,這些解決方案比較流行,但據(jù)我所知,它們已經(jīng)不復(fù)存在了。但是我并不會(huì)馬上認(rèn)為非關(guān)系型的數(shù)據(jù)庫不再重要了。
去年,我編寫了一個(gè)非常復(fù)雜的集成了Parse Server的Android應(yīng)用。 我使用了Android版本的的Parse SDK,體驗(yàn)都非常好。如果您的公司已經(jīng)雇用了許多后端開發(fā)人員,或者您需要實(shí)現(xiàn)許多服務(wù)器端邏輯,這可能不是最佳解決方案,但是對(duì)于僅在后端執(zhí)行CRUD操作的初創(chuàng)企業(yè)和個(gè)人來說,這可能會(huì)是一種好的選擇。
但是我必須提醒的一點(diǎn)是:如果您要采用數(shù)據(jù)庫即服務(wù)的解決方案(例如Firebase),那么請(qǐng)務(wù)必了解其長(zhǎng)期的成本和影響。
External Storage
關(guān)于外部存儲(chǔ)的開發(fā),這里有許多有“意思”的事情。
如果您應(yīng)用的target sdk版本等于或者大于29,那么你的應(yīng)用將無法再正常訪問手機(jī)外部存儲(chǔ)上的文件,除了少數(shù)幾種明顯的情況。 相反,您需要使用SAF框架(據(jù)說),該框架允許用戶進(jìn)行更精細(xì)的訪問管理。不幸的是,SAF的工作方式與之前完全不同,因此某些應(yīng)用程序可能需要進(jìn)行重大重構(gòu)。
Google希望從Android 10開始對(duì)所有的應(yīng)用程序都實(shí)行這一要求,但它引起了開發(fā)者社區(qū)的強(qiáng)烈抗議,于是他們決定推遲此功能。 因此,即使您的應(yīng)用設(shè)置target sdk版本為 29,它仍可以在“舊版”模式下工作。 但是,無論目標(biāo)API級(jí)別是多少,下一版的Android系統(tǒng)都將對(duì)所有應(yīng)用的存儲(chǔ)訪問范圍做更加嚴(yán)格的限制。
到目前為止,我還沒有使用SAF框架,但是從我在互聯(lián)網(wǎng)上閱讀的許多討論中看來,這可能是一項(xiàng)艱巨的任務(wù)。因此,如果您的應(yīng)用程序還在以“舊版”模式使用外部存儲(chǔ),那么最好立即開始進(jìn)行重構(gòu)和測(cè)試。
Shared Preferences
幾周前,AndroidX系列中添加了一個(gè)新框架(https://www.techyourchance.com/the-state-of-native-android-development-november-2019)。它的commit message是這么說的:
New library meant to replace SharedPreferences. The name is not final, this is just for implementation review and to support the design doc (feel free to request the design doc privately)[…]
目前我們無需擔(dān)心,但從長(zhǎng)遠(yuǎn)來看,似乎SharedPreferences會(huì)被重寫,我們需要使用這種新的方法。
SharedPreferences和這個(gè)新框架之間的主要區(qū)別在于,默認(rèn)情況下后者是異步的。 換句話說,您需要實(shí)現(xiàn)一個(gè)回調(diào)以獲取特定鍵的值,該回調(diào)將在以后的某個(gè)時(shí)間收到通知。
如果您對(duì)這種異步通知的機(jī)制感到好奇,則可以閱讀StackOverflow上的這個(gè)答案(https://stackoverflow.com/questions/37549578/how-to-get-something-useful-from-this-anr-log/37551254#37551254)。Reddit用戶Tolriq在這里分享了他們遇到此bug的概率。在他們的應(yīng)用中,這個(gè)bug會(huì)影響1 / 10,000 / SESSIONS_PER_USER_PER_MONTH的用戶。對(duì)于一般的應(yīng)用程序,這可能微不足道。但是在需要高可靠性的情況下,這可能會(huì)引起嚴(yán)重的后果。例如,在裝有Android Auto的汽車中,應(yīng)用程序掛起和隨后的崩潰會(huì)分散駕駛員的注意力,這可能會(huì)導(dǎo)致非常不幸的后果。
Dependency Injection
在依賴注入方面,最大的變化就是Dagger-Android的棄用。這里我想解釋兩點(diǎn):首先,我說的棄用并不是指“正式”棄用,因?yàn)樗形凑綏売?。其次,Dagger-Android并不是整個(gè)Dagger2框架,而只是相對(duì)較新的功能。我在這個(gè)主題上寫了一篇非常詳盡的文章(https://www.techyourchance.com/dagger-android-dead/),所以我在這里不再重復(fù)。
至于其他依賴注入框架,我不認(rèn)為它們是Dagger的真正競(jìng)爭(zhēng)者。 例如,Koin也許不錯(cuò),但我認(rèn)為它不會(huì)吸引很多人。 實(shí)際上,我相信它僅由于兩個(gè)主要原因而得到了初步采用。 第一個(gè)是Dagger的糟糕文檔,Koin在這方面要比Dagger領(lǐng)先N光年。 第二個(gè)原因是Koin是用Kotlin編寫的,它借著kotlin發(fā)展的浪潮開始興起。 到目前為止,這波浪潮已經(jīng)幾乎消逝。
我認(rèn)為可能會(huì)發(fā)生的情況是,純依賴注入的框架(又稱為手動(dòng)依賴注入)會(huì)逐漸出現(xiàn)。
現(xiàn)在,谷歌聲稱“隨著應(yīng)用程序的不斷增大,手動(dòng)依賴項(xiàng)注入成本呈指數(shù)增長(zhǎng)”。 我認(rèn)為,這僅表明他們既不了解“指數(shù)”的含義,也沒做過任何實(shí)際的“測(cè)量”。 此聲明是完全錯(cuò)誤的,我希望Google不要以這種方式來誤導(dǎo)社區(qū)里的開發(fā)者了。
事實(shí)上,純依賴注入在后端開發(fā)中非常普遍(尤其是在開發(fā)微服務(wù)的時(shí)候,您不想在其中添加對(duì)每個(gè)服務(wù)的框架的依賴),反射也是后端開發(fā)中的一個(gè)有效的選項(xiàng)。 因此,如果要使用依賴注入框架,他們通常不需要解析編譯時(shí)代碼。
但是,Android開發(fā)的情況有所不同。由于我們不能使用反射式DI框架,所以我們使用了Dagger。事實(shí)上,我們可以使用反射式DI框架,并且對(duì)于大多數(shù)項(xiàng)目來說都可以,但是卻存在性能問題。我并不是說使用反射式DI框架是安全的,但它絕對(duì)不是一種非黑即白的方案。無論如何,Dagger已經(jīng)是在Android開發(fā)中使用依賴注入的事實(shí)上的標(biāo)準(zhǔn),我們都使用它。但使用Dagger的代價(jià)也很明顯:
1)應(yīng)用的代碼越多,在構(gòu)建過程中運(yùn)行注解處理所花費(fèi)的時(shí)間就越多。
2)應(yīng)用參與的開發(fā)人員越多,他們需要執(zhí)行的構(gòu)建次數(shù)就越多。
3)所有開發(fā)人員都需要學(xué)習(xí)Dagger ,這需要很多時(shí)間。
換句話說,雖然Dagger確實(shí)允許您編寫更少的代碼,但由于它會(huì)影響構(gòu)建時(shí)間和所需的培訓(xùn)時(shí)間,因此在大型項(xiàng)目上它會(huì)花費(fèi)更多的時(shí)間。
在大型項(xiàng)目中,構(gòu)建時(shí)間慢才是真正的問題,并成為主要的生產(chǎn)力瓶頸。 因此,盡管Dagger確實(shí)提供了非常出色的功能來簡(jiǎn)化DI(當(dāng)然,一旦您知道如何使用它),但我相信我們對(duì)純依賴注入會(huì)產(chǎn)生越來越多的興趣。
DataBinding
開發(fā)人員采用DataBidning的主要原因之一是不再需要調(diào)用findViewById了。 老實(shí)說,findViewById確實(shí)很冗余,我也不介意擺脫它們。 但是,在我看來,調(diào)用findViewById帶來的小麻煩并不能證明使用DataBinding是合理的。 好消息是,很快我們將能夠使用另一個(gè)新功能ViewBinding來刪除這些findViewById的調(diào)用。
實(shí)際上,我從來都不相信DataBinding。對(duì)于它(應(yīng)該)解決的問題,我感覺太復(fù)雜了。 此外,DataBinding允許開發(fā)人員將邏輯放入XML布局中。 經(jīng)驗(yàn)豐富的開發(fā)人員是不會(huì)使用這種方法的,因?yàn)檫@增加了項(xiàng)目維護(hù)的難度。這是DataBinding框架的另一個(gè)缺點(diǎn)。
早在2016年11月,當(dāng)DataBinding正處于大肆宣傳的頂峰時(shí),我在StackOverflow上的一個(gè)答案(https://stackoverflow.com/questions/4916209/which-architecture-patterns-are-used-on-android/30628530#30628530)中做出了以下預(yù)測(cè):
However, there is one prediction I can make with a high degree of confidence: Usage of the Data Binding library will not become an industry standard. I’m confident to say that because the Data Binding library (in its current implementation) provides short-term productivity gains and some kind of architectural guideline, but it will make the code non-maintainable in the long run. Once long-term effects of this library will surface – it will be abandoned.
現(xiàn)在,關(guān)于DataBinding的使用率,我沒有任何統(tǒng)計(jì)數(shù)據(jù),但是很明顯,它并沒有成為行業(yè)標(biāo)準(zhǔn)。 我自己還從未見過使用DataBinding的專業(yè)項(xiàng)目,也很少見到在其應(yīng)用中使用DataBinding的開發(fā)人員。據(jù)我估計(jì),一旦ViewBinding成熟并被廣泛采用,DataBinding將會(huì)更加流行,并成為“傳統(tǒng)”框架。
Preserving State on Configuration Changes
自從引入ViewModel之后,在Android應(yīng)用中對(duì)于配置更改的處理就變得一團(tuán)糟。 我知道我的這種說法太苛刻了點(diǎn),但實(shí)際上,這是我可以描述的最溫和的表達(dá)方式。
對(duì)我來說幸運(yùn)的是,Gabor Varadi(又名Zhuinden)已經(jīng)在Reddit上的這篇文章(https://www.reddit.com/r/androiddev/comments/b908fr/can_someone_explain_to_me_why_aac_is_trying_to)中對(duì)這一問題進(jìn)行了總結(jié),所以我不需要自己做。他的結(jié)論就是:不推薦使用onRetainCustomNonConfigurationInstance,而推薦使用ViewModel。有趣的是,在該帖子的結(jié)尾,Gabor做了一些頗具嘲諷味道的預(yù)測(cè):
你發(fā)現(xiàn)什么了嗎? Retained Fragments現(xiàn)在已經(jīng)被棄用了!。
我認(rèn)為,棄用Retained Fragments實(shí)際上是一個(gè)好主意。Fragment的生命周期里具有onAttach和onDetach這兩個(gè)方法的唯一原因就是為了支持Retained Fragments的使用。通過棄用Retained Fragments,這些方法也可以棄用,并且可以簡(jiǎn)化Fragment的生命周期。如果您使用我的方法(https://www.techyourchance.com/android-fragment-lifecycle-for-professional-developers)來處理Fragment的生命周期,那么這種棄用就不會(huì)讓您感到困擾,因?yàn)槲议L(zhǎng)期以來一直建議您避免Retained Fragments,忽略onAttach和onDetach方法。
盡管有充分的理由要棄用Retained Fragments,但棄用onRetainCustomNonConfigurationInstance卻是胡說八道。 這不是我說的,而是Jake Wharton說的(您可以在前面提到的Gabor在Reddit上的帖子下閱讀他的原話)。
為什么要做這些變動(dòng)呢?我只能看到一種解釋:Google決定不管其它技術(shù)優(yōu)勢(shì)如何,都強(qiáng)制將所有Android項(xiàng)目遷移到ViewModel。 他們?cè)敢鈼売盟鞋F(xiàn)有的替代方案以實(shí)現(xiàn)其目標(biāo),即使這些替代方案實(shí)際上優(yōu)于ViewModel本身。
聽起來有點(diǎn)陰謀吧? 我同意。 但是,幸運(yùn)的是,我們可以對(duì)此理論有一個(gè)簡(jiǎn)單的檢驗(yàn)。
雖然我不喜歡Preserving State on Configuration Changes,但它不會(huì)以任何方式影響我,因?yàn)槲覜]有使用它。 實(shí)際上,絕大部分應(yīng)用程序都不需要它。 它們也不需要ViewModel。正確處理Configuration Changes的方式就是在onSaveInstanceState(Bundle)回調(diào)方法里增加處理邏輯。 這是一種更簡(jiǎn)單,更好的方法,因?yàn)樗€可以處理保存和恢復(fù)流程(也稱為進(jìn)程終止)。 因此,只要我能以這種方式保存狀態(tài),就可以了。 盡管Google進(jìn)行了大量的營(yíng)銷和公關(guān)工作,但許多經(jīng)驗(yàn)豐富的開發(fā)人員都意識(shí)到ViewModel太復(fù)雜了,并且有更好的方法來保留配置更改的狀態(tài)。
因此,如果Google確實(shí)有別有用心,并且想迫使所有項(xiàng)目都使用ViewModel,那么他們還需要棄用onSaveInstanceState(Bundle)。 我知道這聽起來很瘋狂,但這實(shí)際上是件好事,因?yàn)槿绻@種瘋狂的預(yù)測(cè)成真,您就會(huì)知道基礎(chǔ)理論是正確的。
但是,鑒于Android的內(nèi)存管理機(jī)制,Google不能僅在不提供可靠替代方案的情況下就棄用onSaveInstanceState(Bundle)。 “幸運(yùn)”的是,這些變化已經(jīng)應(yīng)用在ViewModel的保存狀態(tài)模塊上了。
我想在一兩年內(nèi)我們就會(huì)知道這種做法是否有任何優(yōu)點(diǎn)。‘
總而言之,正如我在本節(jié)開頭所說的那樣,自ViewModel發(fā)布以來,Android中的Configuration Changes就成了屎。兩年多以前,當(dāng)我撰寫題為“Android ViewModel Architecture Component Considered Harmful”(https://www.techyourchance.com/android-viewmodel-architecture-component-harmful)的文章時(shí),我預(yù)測(cè)ViewModels將是一種浪費(fèi)。我的所有預(yù)測(cè)都是真實(shí)的,但不幸的是,事實(shí)證明真相比這還糟。
Concurrency
在并發(fā)這方面,最大的變化就是AsyncTask的棄用。我已經(jīng)寫了一篇有關(guān)此主題的非常詳細(xì)的文章(https://www.techyourchance.com/asynctask-deprecated),并提出了具體建議,因此在此不再贅述。
接下來我說的話可能會(huì)使部分讀者感到不滿。拜托,別太把這事當(dāng)真。
Android開發(fā)中另一個(gè)流行的多線程框架RxJava很快就會(huì)成為“過去式”。 從下面這幅StackOverflow趨勢(shì)圖可以明顯看出:
許多開發(fā)者會(huì)質(zhì)疑我的觀點(diǎn),稱該數(shù)據(jù)不具有代表性,并且還有其他方法的可以解釋該圖。他們可能是正確的,因?yàn)槲易约阂膊皇菙?shù)據(jù)科學(xué)家。但是,在此圖中,我看不到任何其他關(guān)于峰值的解釋,而且RxJava的曲線與AsyncTask的曲線具有相同的斜率。
因此,如果您尚未花時(shí)間在學(xué)習(xí)RxJava上并且您的項(xiàng)目沒有使用它,那么我建議您避免使用它。實(shí)際上,這一直是我的建議,今天它也得到了數(shù)據(jù)的支持。
如果您的項(xiàng)目已經(jīng)使用了Rx,也請(qǐng)不要驚慌,您無需立即重構(gòu)任何東西。但是,請(qǐng)記住,今后找到具有Rx經(jīng)驗(yàn)的開發(fā)人員將越來越困難。 因此,在項(xiàng)目中廣泛使用Rx可能需要新的開發(fā)人員投入更多的時(shí)間。最終,廣泛使用Rx的項(xiàng)目將被視為“not cool”(例如今天使用AsyncTask和Loaders的項(xiàng)目)。
我知道我的這些觀點(diǎn)對(duì)于許多開發(fā)人員來說很不友好。他們花了數(shù)周時(shí)間來學(xué)習(xí)RxJava,甚至說服了同事在項(xiàng)目中使用RxJava,現(xiàn)在我卻說它會(huì)成為“過去式”。我只想說我只是分析實(shí)際情況并根據(jù)我所看到的做出預(yù)測(cè),我可能是錯(cuò)的,也可能是對(duì)的。
在Kotlin語言中,我們可以使用協(xié)程。我最近使用協(xié)程實(shí)現(xiàn)了一些復(fù)雜的用例(https://www.techyourchance.com/kotlin-coroutines-in-complex-scenarios),發(fā)現(xiàn)此框架非常的細(xì)微和復(fù)雜,并且相對(duì)不成熟,我甚至發(fā)現(xiàn)了一個(gè)bug。
有一種流行的說法是,協(xié)程使得并發(fā)處理更簡(jiǎn)單。我從來不這樣認(rèn)為,因?yàn)槲抑啦l(fā)是非常復(fù)雜的,但是在我有了一些實(shí)踐經(jīng)驗(yàn)之后,我可以自信地說,協(xié)程并沒有想像中的那么美好。在我看來,協(xié)程實(shí)際上增加了程序復(fù)雜性,所以我建議你們小心地使用它們。
另一方面,協(xié)程似乎將成為Kotlin語言里處理并發(fā)操作的默認(rèn)方式。因此,我認(rèn)為如果您編寫Kotlin代碼,您需要投入時(shí)間并學(xué)會(huì)使用它們。
據(jù)我所知,目前還有一個(gè)流式框架,它在協(xié)程之上添加了流處理操作符。幾個(gè)月前才穩(wěn)定下來,所以我現(xiàn)在還不能說什么。
Kotlin
現(xiàn)在讓我們來討論一下Kotlin。根據(jù)以往的經(jīng)驗(yàn),我知道這是一個(gè)非常敏感的話題,而且不管我描述的多么客觀,最終都會(huì)遭受一些開發(fā)者的攻擊。然而,我認(rèn)為在總結(jié)原生Android開發(fā)現(xiàn)狀的時(shí)候跳過Kotlin是極不誠(chéng)實(shí)的。因此,我再次請(qǐng)你不要把我說的話當(dāng)真。
你所需要知道的一個(gè)重要的事實(shí)是:在Android開發(fā)中使用Kotlin會(huì)嚴(yán)重增加你的構(gòu)建時(shí)間。
在這篇文章(https://eng.uber.com/measuring-kotlin-build-performance)中,您會(huì)了解到我在使用Kotlin進(jìn)行開發(fā)時(shí)對(duì)構(gòu)建時(shí)間所進(jìn)行的統(tǒng)計(jì)測(cè)試的結(jié)果。clean build 增加了18%的構(gòu)建時(shí)間,incremental build 增加了8%的構(gòu)建時(shí)間。
Uber與JetBrains也聯(lián)合發(fā)表了他們自己的研究結(jié)果,他們的結(jié)果更為負(fù)面。如果您不在應(yīng)用程序中使用注解處理器,那么引入Kotlin可能會(huì)使您的構(gòu)建時(shí)間增加四倍!如果您使用了注解處理器,那么引入Kotlin會(huì)使您的構(gòu)建時(shí)間增加50%-100%。
Uber的研究結(jié)果與將OkHttp遷移到Kotlin版本后構(gòu)建時(shí)間增加了4倍的結(jié)果是一致的。
如果您對(duì)這些數(shù)字感到驚訝,您不用擔(dān)心-這不是您的錯(cuò),而且您并不孤單。盡管這個(gè)事實(shí)極為重要,但它并未得到廣泛討論,并且我覺得Google也試圖回避這個(gè)事實(shí)。我曾與Google內(nèi)部一個(gè)熟悉此事的開發(fā)人員有過一次非常有趣的討論,我問他是否可以討論下這個(gè)話題,他說:“我不喜歡;我不喜歡;我不喜歡。這是一件很微妙的事情?!?/p>
除了增加構(gòu)建時(shí)間之外,Kotlin還不支持增量注解處理,而在大約10個(gè)月前Java就已經(jīng)支持增量注解處理了。
兩年前,我寫了一篇文章(https://www.techyourchance.com/kotlin-vs-java-whole-story)來警告開發(fā)者們?cè)谠缙谑褂肒otlin時(shí)可能會(huì)遇到的潛在風(fēng)險(xiǎn)。在很長(zhǎng)一段時(shí)間內(nèi)我被稱為“kotlin的討厭者”。
但是,如果您今天閱讀這篇文章,您會(huì)發(fā)現(xiàn)我實(shí)際上低估了這些問題的嚴(yán)重性。在大型的Android項(xiàng)目上,構(gòu)建時(shí)間是最糟糕的生產(chǎn)力殺手之一,而且即使在今天,即Kotlin被官方“正式采用”兩年多之后的今天,Kotlin仍然不如Java。不管Kotlin帶來什么其他好處,所有這些都可能由于更長(zhǎng)的構(gòu)建時(shí)間而被否定。
也就是說,我們不應(yīng)改忽視這樣一個(gè)事實(shí):是谷歌將android開發(fā)的生態(tài)強(qiáng)行推向了kotlin,使得其使用率在穩(wěn)步上升。
就我個(gè)人而言,我并沒有在我目前已經(jīng)開始的新項(xiàng)目中選擇kotlin語言,我不想在kotlin上浪費(fèi)我自己的時(shí)間。不過,從現(xiàn)在開始,我會(huì)認(rèn)真考慮使用kotlin來開發(fā)新項(xiàng)目,我已經(jīng)在幾個(gè)demo上嘗試過了。但是我不同意開發(fā)人員說你必須在新項(xiàng)目中使用Kotlin,這仍然是一種權(quán)衡。
至于你們是否應(yīng)該將現(xiàn)有項(xiàng)目遷移到Kotlin,我無法提供任何一般性建議,您需要根據(jù)具體的情況進(jìn)行仔細(xì)的分析。但是,如果您確實(shí)決定開始(或已經(jīng)開始)遷移,那么這個(gè)帖子可能會(huì)對(duì)您有用。
Summary
在過去的兩年中,我開發(fā)了三個(gè)新的應(yīng)用程序。我認(rèn)真研究了現(xiàn)有的項(xiàng)目并分析了早期技術(shù)決策所帶來的長(zhǎng)期影響。我寫了一些博客,提供有關(guān)Android開發(fā)的高級(jí)課程。我花了很多時(shí)間在互聯(lián)網(wǎng)上討論Android開發(fā)相關(guān)主題。
盡管如此,我還是感覺自己無法跟上Android生態(tài)系統(tǒng)的變化。
如果是這樣的話,對(duì)于那些缺乏經(jīng)驗(yàn)、需要指導(dǎo)的Android開發(fā)人員,我深表歉意,而且我至今無法想象從頭開始學(xué)習(xí)Android開發(fā)的感覺。當(dāng)您對(duì)框架和工具感到滿意的時(shí)候,其中許多將已過時(shí)或即將過時(shí)。加入這個(gè)原本很棒的社區(qū)可能是最糟糕的時(shí)刻。Google為他們的“包容性”感到非常自豪,但看起來它不適用于經(jīng)驗(yàn)不足的開發(fā)新手。
我個(gè)人認(rèn)為Google對(duì)Android框架所做的更改會(huì)導(dǎo)致巨大的人類潛力浪費(fèi)。閱讀所有這些更改需要花費(fèi)數(shù)小時(shí),更不用說實(shí)際實(shí)施它們了。我寧愿花更多的時(shí)間來創(chuàng)造價(jià)值,而不是追逐自己的尾巴。
在這篇文章中,我試圖總結(jié)有關(guān)Android原生開發(fā)現(xiàn)狀的一些重要的內(nèi)容,我還對(duì)未來做了一些預(yù)測(cè)。這篇文章并不完美:它可能包含一些錯(cuò)誤,而且還錯(cuò)過了一些其他重要內(nèi)容。請(qǐng)隨時(shí)在下面的評(píng)論中糾正我。但是請(qǐng)記住,本文沒有任何私人內(nèi)容。我知道我提出了一些非常有爭(zhēng)議的觀點(diǎn),但是我相信這是對(duì)的。
我還在本文的多個(gè)地方引用了我之前寫的一些文章。我這樣做并不是為了炫耀并說“看,我是正確的!”,而是讓您能夠了解我過去的預(yù)測(cè)并將其與實(shí)際發(fā)生的情況進(jìn)行比較。當(dāng)我寫這些文章時(shí),他們讀起來就像您今天讀本篇文章一樣瘋狂。但是我所做的預(yù)測(cè)卻非常準(zhǔn)確。
當(dāng)然,我也想說:“看,我是對(duì)的!”。我冒著巨大的專業(yè)風(fēng)險(xiǎn)發(fā)表了這些有爭(zhēng)議的預(yù)測(cè),在得知自己沒有誤導(dǎo)讀者后我感到非常的欣慰。即使有時(shí)候我寧愿自己是錯(cuò)的,也希望Google成為真正的合作伙伴。但是到目前為止,情況并非如此。
最后附上文章作者對(duì)于跨平臺(tái)開發(fā)的一些看法,僅供參考。
學(xué)不動(dòng)也要學(xué)!深入了解ViewPager2
Effective Java in Kotlin:2. 遇到多個(gè)構(gòu)造器參數(shù)時(shí),考慮用構(gòu)建者
誰天生就是干程序員的料?
大家覺得哪個(gè)趨勢(shì)更先普及呢?
本文標(biāo)題:敢問路在何方?Android原生開發(fā)現(xiàn)狀剖析
文章轉(zhuǎn)載:http://m.fisionsoft.com.cn/article/cdpcedc.html


咨詢
建站咨詢
