Android 開發者成神之路

一個 Android 技術專家,至少有 2~3 個專業領域。

原文:Android Developer Skills for 2020
作者 | Vasiliy Zukanov,獨立 Android 開發及軟件顧問,已獲作者翻譯授權
譯者 | 羅昭成,Android 開發者,責編 | 唐小引
本文首發 CSDN(ID:CSDNnews)

以下爲譯文:

許多 Android 開發者經常會問我,要學會哪些東西才能成爲一個優秀的 Android 工程師?對於這個問題,他們的描述或多或少都有些差異,但是,總體來說,我們都需要學習一系列的技能,才能成爲一個優秀的 Android 工程師。

在我看來,存在這樣的困惑是正常的。Android 是一個巨大並且動態的生態系統,你可能需要花好幾周時間去了解並學習它相關的一些工具和概念,但是最後你會發現,它們有好多都不是很重要,或者說並不是非常有用。因此,在本文中,我將分享我在 Android 開發中所使用到的重要技能,希望能夠幫到你,讓你把你的精力集中到重要的事情上。

當然,如果你是一個經驗豐富的 Android 開發者,這些知識可能你都知道。有很多技能和觀點都需要很多基礎知識的沉澱,當你沒有足夠的經驗的時候,很難看到這些技能點。文中,我不可能列出所有 Android 開發者都需要的技能。所以,我根據不同的經驗,將這些知識點進行了粗略分組。請注意,這只是一個粗略的分組,並不一定是很精確的。

寫在前面

如果你只是一個想成爲 Android 開發者的人,並且還沒有寫過任何應用,那麼這篇文章對你來說,還有點太早。本文主要是爲了幫助開發者成爲一個更專業的人。

本文,我會給你很多建議,不會讓你空手而歸。文章中列出瞭如何在短時間成爲一個專業的開發者。讀完文章,需要你自己去練習,並時常回來看看這些技能。

在本文開始之前,我就當你已經在 Google Play 發佈過 Android 應用並且使用 Github 來進行源碼管理。

0-2 年開發經驗

Android 是一個非常複雜的框架,它擁有陡峭的學習曲線。有一些複雜的概念的確是 Native 的 Android 開發者需要學習的,但另一部分卻是由於 Android 的原因,造成了它的複雜度。

當你像專業進軍時,除了你的軟件開發工作以外,你應該學習 Android 框架,忘記語言、架構、流行的開源庫,專注於核心概念,並進行深入的研究。

具體來說,我建議你更多的瞭解以下內容:

Android 內存管理和進程調度

當面臨「Low Memory Killer」的時候,如何保證你的應用程序穩定可靠的運行?這是一件很複雜的事情。長話短說,當用戶切換到其它應用時,你應用的生命週期就會被打亂,但是當用戶過一會兒重新切換回來的時候,用戶卻希望你的應用程序像任何事情都沒有發生過一樣,正常運行。

在本文中,我並不會介紹內存管理的任何細節,如果你想了解它們,可以看看這篇文章 .

生命週期

如果有人要我說出 Android 應用程序中的複雜度和 Bug 的主要來源,我會立馬大聲告訴他是“生命週期”(然後捂住臉哭).

Application、Activity、Fragment、Service、BroadcastReceiver、ContentProvider 和一些 Android 框架的核心組件,都擁有複雜的生命週期,並且它們的生命週期還不一樣。如果你覺得這還不夠多,Google 也一直在推出新的庫和框架,這些庫都有自己的複雜性和獨立的生命週期。Loader, ViewModel 和 LiveData 都是爲了解決這些問題而推出的。

有件有意思的事情,我從來沒有看到過任何有關“生命週期“的定義。我們一直在使用它,但是它到底是什麼意思呢? 據我所知,在某種程度上,你只是把一些節點串聯在一起,構建出一個生命週期的圖。我對生命週期有過很多的思考,在這裏,我將嘗試對它進行定義。

組件的生命週期是一個抽象的狀態機。這裏的抽象的意思是指,這些狀態機的狀態是預先定義好的,它們之間的轉換條件也是定義好的。但是這些定義是不完整的。你需要去實現缺少的部分,使他們可以正常工作。這些缺少的部分是這些組件方法的子集,我們稱其爲“生命週期回調”,除了狀態機本身之外,這些生命週期回調中,也有很多隱式的限制和約束。這些限制有些寫在了文檔中,而有些卻並沒有記錄。

生命週期到底有多複雜?我們先來看一下這張圖 (它有點不完整,還有點過時)。這張圖,看起來有點可怕。不過,你也不要慌,大多數 Andorid 開發者都搞不明白這個圖。事實上,即使 Google 的 Android 開發者也搞不明白生命週期的問題。Google 在發佈 Lifecycle 組件的時候,裏面引入了一些有關 Fragment 的 bug, 直到後續的新版本發佈了才得以修復。

雖然現在你不需要完全掌握 Android 的生命週期,但是你必須要知道一些重要的細節。否則,你的代碼會變得混亂不堪,並且容易出現一系列難以解決的問題。我寫了兩篇文章Activity 生命週期Fragment 生命週期 ,描述了生命週期的細節。當你不知道如何使用 onStartonResume 時,你可以去看看這兩篇文章。

當你掌握了生命週期的基礎知識,你可以去看看 Gabor Varadi 寫的Android 開發的十宗罪 ,這篇文章,列舉出了大多數開發者都會犯的錯誤。這些錯誤大多數都與生命週期有關。

順便說一下,在面試中,生命週期相關的問題也會被經常問到。這也是你必須好好學習生命週期的原因。

Context

在每一個 Android 應用程序中,都有一個或多個上下文對象。

和生命週期一樣,它也很難被解釋。它就像是一個“上帝類“一樣,它有非常多的能力。我們很難用一兩句話就把它描述清楚。儘管如此,理解 Context 職責和不同 Context 之前的區別也是非常重要的。

本文中,沒有更多關於 Context 的內容,我建議你去讀一下 StackOverflow 中關於 《What is ‘Context’ on Android?》 的回答和這個回答的內容.

UI 線程

每一個 Android 應用程序都有一個特殊的線程 —— UI 線程。這一個線程在屏幕上繪製出 UI 頁面。如果你讓 UI 線程超負荷運行,你的應用程序將會變得卡頓,不響應。在極端情況下,UI 線程中的錯誤會導致整個應用程序出錯(至少看起來像是出錯了)。

如果你想詳細瞭解線程背後的機制原理,你可以去看這個視頻,視頻中詳細解釋了 Android 中的多線程,包含 UI 線程的相關細節和可能存在的問題。

邏輯拆分

從整體上說,Android 框架的代碼很不“整潔”。它包含着很多的上帝類,這些類中,每一個有數千行代碼,並且我們還必須去擴展這些類,才能讓我們的應用程序運行起來。在多數情況下,不管是 Application, Activity ,Fragments 還是 Service,我們都是在一個很大的類中,做很多的事情。

雖然在 Andorid 開發中,這是一個常見的做法,但這樣子做並不利於長期維護我們的代碼邏輯。因此我建議,要儘可能的注意這個問題,多找機會去重構代碼,將邏輯拆分到獨立的類中去。

說實話,我現在並不認爲,一個初級開發者可以對架構和設計做出太多的改善工作。正確的封裝代碼邏輯,提取出有意義的類,都需要一些開發經驗。當然,我也不希望你不去思考代碼拆分,你可以做一些力所能及的事情,避免出現不可控的情況(例如,一個 Activity 中寫了超過 5000 行代碼)。

剛開始,你可以嘗試拆分這篇文章中描述的與 Context 有關的邏輯。

2-4 年開發經驗

當你在你的職業生涯中工作幾年,你變成經驗豐富的 Android 開發者,通過研究和學習,你可以很輕鬆的實現一些非專業化的功能。那下一步,你該做什麼?

我認爲,在這個時候,你已經很熟悉 Android 框架的基礎知識了,可以嘗試去學習更高層次的技能。這些技能不侷限於 Android,它們是一些通用的軟件開發的技能。具體來說,你可以研究以下主題:

依賴注入

依賴注入是一個關注結構分離的設計模式。它主要是用來進行分離應用程序的兩個功能:

  1. 應用程序和核心功能
  2. 核心功能組件實現之間的鏈接

從某些方面來說,實現了依賴注入的代碼庫就好你一個計算機:依賴注入的基礎庫就像是主板一樣,而其他的功能組件就好像是 CPU、內存、外設等。只要你的代碼中實現了依賴注入,你就可以很方便的插入新功能,並且可以很容易的重用其它組件的功能,也可以很方便的使用新組件的功能。雖然這個比喻有點誇張,但是在我看來,它也確實很好的反映了依賴注入背後的思想。

不幸的是,現在關於依賴注入的文章,很多都存在誤解,這給初學者帶來很多幹擾。因此,如果你想學習依賴注入,我建議你讀一下這篇文章,本文中,我分析了衆多依賴注入的“神話“。

UI 分離

由於 Android 框架本身的架構,造成了我們在開發的過程中,使用戶頁面與應用程序中的其它邏輯耦合在一起。幾乎所有的 Android 初學者都會這樣。這種耦合會導致我們寫一個很大的類,這個類裏面有應用程序的 UI 繪製、網絡處理、多線程處理、應用業務邏輯等。

根據我的經驗,UI 邏輯與其它邏輯耦合在一起,會導致代碼的可維護性越來越差,遲早會使用代碼變得難以理解,無法閱讀。到最後,可能會因爲功能上的一點小變化,引起很大的副作用。

要將 UI 邏輯與其它邏輯進行分離,可以用使用 Model- View - X 的架構模式。例如: Model-View-Contoller(MVC)、Model-View-Presenter(MVP)、Model-View=ViewModel(MVVM)。這些架構模式都屬於同一類架構,當然,這一類架構不僅僅包含列舉的這幾個,還有其它的架構模式。在這裏,爲了更方便的描述這一類架構模式,我把他們統稱爲 MVx 模式。

當你在學習 MVx 模式的時候,請記住,這些都不是架構,而是一種架構模式。這些架構模式僅用於 UI 展示邏輯。因此僅僅使用 MVx 並不能給你一個好的架構,要有一個好的架構,你還需要在其它方面做出更多的努力才能實現。

多線程

有經驗的 Android 開發者都會了解多線程,並且瞭解他們對應用程序的影響。你也許會說,我精通 AsyncTask、RxJava、協程等。我想表達的多線程不是你理解的這個。會使用多線程框架並不等同於理解多線程。

舉個例子,衆多 Android 開發者都認爲,使用 AsyncTask 會導致內存泄漏。這個觀點來自 Android Studio 默認的多線程 lint 規則中。既然如此,那這個觀點就是對的了嗎?很不幸,這個觀點是錯誤的。在這裏,我不講解它們的細節,你可以讀一下這篇文章,裏面有很多關於 AsyncTask 的內容。

我認爲要理解多線程程,就必須可以使用任何多線程框架,甚至是基於基礎的 Thread ,都可以寫出正確的併發代碼。要實現這個目標,你不僅僅需要知道你喜歡的多線程庫的 API,你還需要理解多線程的細節。這些多線程庫雖然好用,但如果你不理解多線程的基礎細節,那麼你的應用程序出現多線程的問題只是時間問題。

如果你想學習多線程,從這個視頻 開始,視頻中講解了所有 Android 開發人員都需要知道的基本概念與原理。

自動化測試

據我所知,很多 Android 項目,都沒有使用任何的自動化測試。在使用自動化測試的項目中,大多數也是 QA 人員使用 Appium 之類的工具來完成的。這是整個 Android 行業的現狀,非常可悲。之所以沒有自動化測試,這個問題可以追溯到 Android 起源,Google 也在很長一段時間裏,沒有關注過第三方應用的自動化測試。

現如今,有單元測試和 UI 自動化測試經驗的開發者需求量很大。即使你到一家沒有使用過任何自動化測試的公司去面試,如果你說你會自動化測試,就會給你的面試加分。反之,如果你去的是一個廣泛使用自動化測試的公司,你沒有自動化測試的技能,這會給你面試減分,處於劣勢。

因此,我建議每一個 Android 開發者都去學習一下自動化測試的相關知識。就個人而言,我更喜歡單元測試。而一些開發者喜歡 UI 自動化測試。所以,可以選擇一個你更感興趣的技術,嘗試一下。

4 年以上經驗

如果你對 Android 已經有了非常豐富的開發經驗,那麼,是時候學習一些“元”技能了,並且在特定領域進行深度研究。在我看來,以下技能對專業的開發人員來說,都是非常不錯的方向。

技術方案評估

如果你還沒有做過這件事情,那麼現在是時候開始做了。每一個重要的技術決定,都需要進行評估、權衡。有時候,這種決定帶來的結果非常好,立竿見影。但是大多數時候,並非總是能夠立竿見影,看到效果。通常情況下,需要決策的範圍越大,所涉及到的評估範圍就越大,除了可以簡單進行決策的事情,還有很多可評估項都是非常抽象,短時間內根本看不到結果的。

在自己豐富的經驗水平下,面對衆多選擇,你至少應該知道如何找到取捨。如果你能對技術方案評估提供有用的建議,你就非常優秀了。技術方案評估權衡這是一項非常複雜的技能。通常,在與其它開發者、項目經理甚至是其它部門員工討論的時候,你能找到折中方案,就能進行方案評估。因此,在大數情況下,你只需要掌握評估方案的能力就夠了。

那我們所說的“技術方案的評估”到底是什麼意思?說實話,很難具體說明它是什麼。不過,我們可以提供一些反例,來解釋爲什麼不適合在開發中使用。舉個例子:

  1. 我們應該將多線程的使用遷移到 RxJava, 而不是 AsyncTask, 因爲 AsyncTask 會導致內存泄漏。

    正如我前面所說,AsyncTask 並不會導致內存泄漏。所以上面這句話是錯誤的。說這句話的開發者並沒有深入的研究多線程。此外,他也沒有提到 RxJava 的問題。對於一個項目中的開發人員來說,RxJava 存在一個很陡峭的學習曲線。

  2. 我們應該爲我們的新代碼寫單元測試,並且設定一個長期的目標,覆蓋所有的代碼,以確保我們的代碼質量。

    這句話包含幾個前提,首先,我們現在開始單元測試是不可能的,至少需要開發人員投入時間來學習這種技術。編寫單元測試是一個很明智的決定。我們不能爲所有代碼編寫單元測試,因爲有一些部分是不穩定的。最後,達到特定的覆蓋目標並不會自動提高“質量“。在這個例子中,開發者並不瞭解單元測試,他們無法確定在項目中使用單元測試所涉及的問題和影響。

我希望,你對“技術方案評估”已經有了大致的想法,如果你有一個重要的決定,你需要完成所有必要的調研,如果你依然看不到整個評估中存在的複雜網絡,那可能是你的調研沒有做好。在做決定的時候,有些事情可能超出技術範圍,你也需要考慮你的決策對其它部門同事的影響。

專業領域

如何區分一個技術專家和一個普通開發者? 是我們熟悉的概念的數量嗎?我認爲,在技術方面,區分是否是專家主要在於知識上的深度。

作爲一個技術專家,你應該有一個或者多個專業領域。你知道這些領域的詳細細節,比一般的開者知道的要多得多。你需要持續深入的研究,來保證你的專業深度,瞭解專業領域的最新發展,不會對新的工具和技術感到驚訝。此外,即使你並沒有在任何項目中使用某些技術,你也需要研究這些技術使用上相關聯的各種成本。

現如今,有一個自己的專業領域很難。這不是從博客中挑選幾篇好文章進行閱讀就可以的,也不是讀完幾本好書、上完幾門好課就可以的。當然,通過這些內容進行學習,對你的專家之路都是有幫助的,但是要有自己的專業領域,唯一的方法就是積極參與其中進行學習研究並獲得大量經驗。

我很喜歡物理學家尼爾斯·玻爾說的這句話:

專家就是把領域內所有該犯的錯都犯完的人
An expert is a man who has made all the mistakes which can be made, in a narrow field.

我們可以在哪些領域進行深入研究呢?實際上,幾乎所有的都可以進行深入的研究,在軟件開發領域,沒有任何一個領域會因爲太小而不能設置成專業目標。對此,我也有一些建議:

  • UI
  • 構建系統
  • 離線工作
  • 併發
  • NDK
  • 持續集成
  • 性能
  • 架構
  • 監測
  • 項目管理
  • 專業知識領域

還有很多很多。需要注意的是,上面我列出來的內容,一些並不屬於嚴格的技術領域。只要你能爲你的僱主產生價值,你可以選擇你喜歡的任何領域並進行深入研究。

我認爲,一個 Android 技術專家,至少有 2~3 個專業領域,例如,我的專業領域是:架構、單元測試、併發、依賴注入。我相信,在不久的將來,我能夠將“重構祖傳代碼”添加我的專業技能列表裏面。

所以,如果你有 4 年以上的經驗,你的專業領域是什麼?

總結

以上,這是我建議你,作爲一個專業的 Android 開發者應該具備的技能。

你可能已經發現,我的文章標題是 《2020 年,Android 開發者需要的技能》,但是這篇文章中沒有什麼內容是特定於 2020 年的。我可以在一兩年前寫這篇文章,因爲本文內容適合所有時間,基礎和重要的概念不會經常改變。

現在,如果你對 Android 生態系統的最新發展感到好奇,你可以閱讀我的另一篇文章 ,我總結了 2019 年底 Android 發展的狀況。最後,我在重複一次,如果你想成爲一個優秀的 Android 開發人員,請集中精力,對基礎和重要的事情做深度研究。

一如既往,感謝你的閱讀。你可以在下面留言評論和提問。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章