在 Android 誕生的第十個年頭,Android 手機應用的開發應該變得更加快捷。Google 也一直在聆聽開發者的心聲,盡力的提高開發者在開發 Android 應用的效率。在去年,我們聽到開發者說,Android 開發的生命週期管理很困難,所以我們推出了 lifecycle 元件。我們還聽到,當你對後臺任務進行處理的時候,API 給你了5-6種不同的解決方法,那麼哪一種才是你最該使用的呢?為了解決這些問題,Android JetPack 誕生了。
我們希望 JetPack 不僅能夠提供各種功能的 API,同時,也希望給各位開發者在開發移動應用的時候可以有一個可以依照的藍圖。
Android JetPack是什麼以及其組成部分
什麼是 Android JetPack?Android JetPack 是一套元件、工具和架構指南,我們將現有的 support library 和架構元件聯絡起來。一會兒你們就將看到,這些架構和元件,都是你們非常熟悉和正在使用的。

Android JetPack 由四個部分組成,分別是架構、介面、基礎和行為,每個部分的具體組成部分請檢視下圖

去年我們推出的架構元件,在開發者心中獲得一致好評,架構元件的優點是,你可以通過使用一個或者幾個架構元件,來解決你在開發過程中遇到的問題。在去年的基礎上,今天我們又推出的新的架構元件,分別是:WorkManager、Navigation、Paging。Paging 已經達到穩定版本,WorkManager 和 Navigation 還處在阿爾法的階段。
JetPack 的第二部分是行為,行為種的大部分元件包含了大家都非常熟悉的元件,例如 Download Manager 可以進行大資料的下載,Media&Playback 和Permissions 可以幫助大家在音視訊的處理和獲取許可權,Notifications 是對推送的處理。這些元件有一個通用的特點:他們都是向後相容的。
行為中,我們還加入了一個新的元件:Slices。Slices 提供給應用的一個新的資料遍歷的方式,現在 Slices 已經在 Google Assistant 和 Google Search 中有所體現了。
JetPack 的下一個部分是介面,其中包括 Fragment、Layout、Palette、Animation&Transitions、Auto.TV & Wear、Emoji 等部分。我們希望介面部分不但能夠讓介面更加好看,同時也希望能夠給使用者帶來好的使用者體驗。
JetPack 的最後一個部分是基礎,就像他的名字的一樣,它是大家在應用開發過程中必不可少的一部分。我們推出了 Kotlin Extensions(KTX)、通過利用 Kotlin 語言自身的特性,例如:擴充套件函式、屬性等,KTX 可以幫助大家更好的寫出簡潔的 Kotlin 程式碼。AppCompat 是大家都很熟悉的向後相容庫,之前 v4 和 v7 在大家的開發過程中帶來了不小的麻煩,所以我們對它進行了封裝,推出了 androidx,大家可以通過使用 Android Studio3.2 來使用 androidx
架構元件
去年,我們推出了一套架構指南,並且有一套元件來完成這個架構指南,通過使用架構元件,可以使你的應用變得更加模組化和易於測試和維護。架構元件的宗旨是:讓 Android 開發更簡單。
在去年的 GDD 上 ,我們想大家介紹來4個穩定版本的架構元件他們分別是:Lifecycles、LifeData、Room 以及 ViewModel。就像下圖中展示的,介面元件負責顯示 UI 介面,ViewModel 負責處理 UI 資料,你可以使用 LiveData 來更新資料進而更新 UI 介面。Respository 是一個唯一的資料層結構,你可以使用 Room 來進行資料持久化。

在這一基礎上,我們還推出來 Paging,它可以幫你在 recyclerview 中更好的夾在分頁資料。Paging 庫已經達到的穩定版本。
接下來,我們來看一下處理阿爾法階段的兩個庫,Navigation。 當使用者在使用你的應用時,就像下圖中的一樣,是你為使用者設計來一個個的目的地。並且引導使用者在這些目的地中瀏覽。我們為導航列出來這幾個必須遵循的原則:
- 需要有一個共同的其實目的地
- 導航的狀態需要一個棧來代表的(後進先出)
- 系統和應用的向上和返回按鈕因該為使用者提供統一的體驗
- 很好的支援 DeepLink

讓我們來看一下 Deep Link 的例子(如上圖),在這個應用程式當中,從首頁到類別到內容,一步一步的到了這樣的一個頁面,當然,你的使用者也可能通過一個url直接來到這個介面。當你做為一個開發者,為了給使用者提供這樣的一個一致可預測的體驗,你需要怎麼做呢?,你需要對回退棧做統一。開發者在解決這個問題的時候,要麼是自己把導航庫的邏輯自己完成了,要麼是自己寫了很多程式碼去實現這個功能,但是程式碼不易於維護。並且是容易出錯的。
Navigation 就是為了解決這樣的問題出現的。Navigation 成功的解決了以下問題:
- 處理 Fragment Transactions
- 處理‘向上’和‘返回’
- 支援 Deep Link
- 提供動畫,跳轉效果
Navigation 在 Android Studio 中提供了一個視覺化的導航編輯介面, 這個視覺化的介面是一個xml檔案,下圖是一個xml檔案的例子。

我們說,Acitivty 將會作為 Navigation 的一個切入點,讓 Fragment 成為內容的載體。Activity 只是負責一個全部的導航,二中間的部分我們是交給一個 NavHost 託管的。

具體是實現導航跳轉是使用 NavController 實現的,為了獲取 NavController 我們為大家提供了下面三個方法

如果你要通過一個按鈕來跳轉一個介面,我們為大家提供來一個方便的方法 createNavigateOnClickListener,如果你不想用這個方法,我們還提供來另外一種方法來實現,參照下圖

關於 Navigation 的跳轉動畫,你可以參考下圖:

在導航的時候,我們經常需要傳遞引數,但傳遞引數我們經常需要考慮的一個問題是:我們無法確保型別的安全。所以 Navigation 提供來一個外掛 Safe Args。

一個常見的 DeepLink 型別,通常是一個通知、Shortcuts、Widget、Action 或者 Slices,我們為這些 DeepLink 提供了一個方法叫做 NavDeepLinkBuilder。關於 NavDeepLinkBuilder 的使用方法,可以參考下圖:

另外一些 DeepLink,例如:URL 或者自定義的 Scheme URIs,我們需要在 Navigation 圖中加入<deepLink>
標籤


由於時間關係,我們無法一一介紹 Navigation 的所有方法,所以,我們建議開發者在會後可以親自體驗一下 Navigation

WorkManager
在 Android 開發過程中的另外一部分對於使用者來說是非常重要的,但是也是我們看不見摸不著的,那就是後臺執行。

從最開始,我們為大家提供了 Background Services、AlarmManager,到 API 21 之後,我們為大家提供了 Jobs,對於使用 Google Play 服務的應用,我們又提供了 Firebase Job Dispatcher 和 GcmNetWorkManager。上圖中顯示了應用市場中各個 Android 系統的版本分佈。你為了覆蓋市場上的這些機型,你可能需要寫一段很長的 if 和 else 程式碼來判斷裝置的情況,來選擇合理的 API。
說到來後臺執行,就不得不提裝置電量的問題。在使用 Background Services 的時候,應用經常在後臺自行執行,從而造成裝置電量快速消耗。為了解決這個問題,Android 系統在最近的幾個版本中陸續推出來減少裝置電量消耗的功能,詳細情況請參考下圖:

目前,關於後臺執行的 API,我們選出以下下幾個:

那麼在上圖中的幾個 API 當中,我們應該首選哪一個呢?答案是 WorkManager。
WorkManager 是一個 API,它簡單到只需要一個 dowork() 這樣的操作,就可以很好的控制後臺程式的執行。同時,它支援向後相容。無論你在應用中是否使用 Google Play 服務,你都可以使用過 WorkManager。
舉個例子,例如我們要上傳一張照片,下圖中是我在上傳照片中使用的 WorkManager API

針對上傳圖片這個操作,我們來看一看怎麼寫:

在這個任務裡,我們 override 的一個doWork方法,doWork 方法會在後臺執行哦,任務上傳成功與否,我們在 doWork 方法裡返回。
在建立好一個任務之後,我們還需要建立一個任務請求:

如果我們在上傳圖片的過程中沒有網路怎麼辦?這就需要我們在建立任務的時候新增一個約束條件:

怎樣確定照片是否上傳成功?在這裡我們可以使用 LiveData 來觀察任務狀態:

剛放給大家介紹來一個新的類叫 WorkStatus,它又兩個方法,一個是 getId,一個是 getState

如果我們想在上傳照片之前先壓縮,WorkManager 也提供來幾個這樣的方法,你可以順序的執行或者同步執行這樣的幾個任務。
首先,我們先建立一個壓縮任務,在壓縮任務之後再建立一個上傳任務,然後使用 beginWith 和 then 把剛才的兩個任務依次加群進去,就可以完成這個任務了。

如果說我想上傳多張圖片該怎麼做呢? WorkManager 也為大家提供了一個方法來做這件事情,大家可以依次呼叫 enqueue 這個方法,把多個任務請求依次加入到這個方法中就可以了。

當我們需要選擇一張圖片來進行上傳的時候,需要輸入一個 URI,我們在進行這個任務的時候,需要一個輸入值,在 WorkManager 中,提供來一個 Data 用作這個輸入值,關於這個 Data 的相關介紹,請看下圖:

首先,我們給我們的需要上傳圖片的 URL 一個做一個 bundle,然後把它傳入到我們的任務請求當中:

然後獲取之前存入的引數,進而獲得需要壓縮圖片的圖片地址,然後把壓縮圖片的地址存起來:

我們把這兩個任務串起來,就是一個這樣的 WorkManager 任務鏈:

怎樣取消上傳?取消上傳,你可以使用 cancelWorkById,但是我們不建議你使用 id 作為任務取消時的標籤。

我們建議大家使用 Tags 來對你的任務進行標記:

然後,我們使用 getStatusByTag 來獲得 Tag 的任務或者取消任務。

在後臺任務中,還又一個非常重要的功能,就是同步,同步又一個特點,就是我們不希望在同一個時間有多個同步任務。

為了實現這個的效果,我們為大家提供了 UniqueWork 這個方法:

具體實現的原理如下:

目前 WorkManager 也處於阿爾法階段,歡迎大家在會後使用 WorkManager。
這裡有一些關於 Androd JetPack、Navigation 和 WorkManager 的一些資源,歡迎大家在會後進行訪問。

謝謝大家!

我去推特粉一下這個小姐姐?。