本文譯自Android開發者文件中Android Architecture Components視訊介紹 科學上網觀看完整視訊 轉載請註明出處
應開發者需求,Android Framework 團隊撰寫了一份Android應用構建指南,還開發出了配套的構建元件。這些元件可以持續儲存資料、管理生命週期、模組化你的應用,幫你避免記憶體洩漏,還能讓你不必去寫無聊的模板程式碼。
基本的Android應用需要將資料庫與穩健的UI結合起來,新的元件如Room
,ViewModel
,LiveData
,Lifecycle
讓這個任務變得很簡單。他們被設計成像積木一樣能彼此組合,下面我們來看看他們是如何工作的:
Room
我們用Room處理資料庫,這是一個新的SQLite 物件處理庫,想要用Room 設定表,我們可以定義一個Plain Old Java Object(POJO),隨後我們用@Entity
來標記這個POJO,並建立一個用@PrimaryKey
標記的Id。
@Entity
public class Trail{
public @PrimaryKey String id;
public String name;
pubklic double kilometers;
public int difficulty;
}
複製程式碼
你需要為每個POJO定義一個資料訪問物件(DAO),這裡宣告的方法代表SQLite命令,用來與你的POJO資料互動
@Dao
public interface TrailDao{
//Create,read,update,delete examples
@Insert(onConflict = IGNORE)
void insertTrail(Trail trail);
@Query("SELECT * FROM Traail")
public List<Trail> findAllTrails();
@Update(onConflict = REPLACE)
void updateTrail(Trail trail);
@Query("DELETE FROM Trail")
void deleteAll();
}
複製程式碼
現在來看看插入和查詢的方法,Room 已經將你的POJO物件自動轉化為相應的資料表,這個過程是雙向的。Room 還會在編譯時校驗你的SQLite,如果你拼錯了什麼東西,或是引用了資料庫中不存在的列,它會顯示一條有用的錯誤提示。
LiveData
現在你有了Room資料庫,你還可以使用另一種構建元件:LiveData
,來監控資料庫中的更改。LiveData是一個可觀察的資料容器。也就是說,他可以儲存資料,還會在資料發生改變時提醒你,這樣你就能及時更新UI。LiveData是一個可擴充的抽象類,更簡單一點說,你可以使用MutableLiveData
類。如果你發出數值更改請求,並更新了MutableLiveData
的值,它隨後就會在你的UI中觸發重新整理。更加強大的是,Room自帶對LiveData的支援,你可以同時使用它們。
修改你的DAO讓它返回用LiveData類包裝的物件。
@Dao
public interface TrailDao{
....
@Query("SELECT * FROM Traail")
public LiveData<List<Trail>> findAllTrails();
....
}
複製程式碼
Room會建立一個LiveData物件用來觀察資料庫,然後你就可以寫出這樣的程式碼來更新你的UI
trailsLiveData.observe(this,trails ->{
//Update UI, in this case a RecyclerView
mTrailsRectclerAdapter.replaceItems(trails);
mTrailsRectclerAdapter.notifyDataSetChanged();
}
複製程式碼
最終結果是 如果你的Room 資料庫更新了,他會改動你的LiveData物件內的資料,從而自動觸發UI更新
Lifecycle
不得不說LiveData還有一項很棒的功能,這個元件會留意到生命週期,現在你也許會想,能留意到生命週期的元件是什麼東西?我還擔心你不會問呢!通過神奇的生命週期觀察,LiveData可以瞭解到你的介面何時再螢幕上出現,何時撤離螢幕,是否已被銷燬,它不會向處於非啟用狀態的UI傳送資料庫更新。
它有兩個介面,分別是:Lifecycle Owners
和Lifecycle Observers
。Lifecycle Owner 是指那些有生命週期的物件,比如Activity和Fragment。Lifecycle Observer則會觀察Lifecycle Owner,並且會收到關於生命週期變動的通知。下面來簡要介紹一下經過簡化的LiveData程式碼
abstract public class LiveData<T> implements LifecycleObserver{
@OnLifecycleEvent(Lifecycle.Event.ON_START)
void startup() {...}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
void cleanup() {...}
}
複製程式碼
它同時也是一個Lifecycle Observer。被@OnLifecycleEvent
標註的方法,在相關的Lifecycle Owiner開啟和停止時,解決了初始化和銷燬的問題。這就允許LiveData物件解決自身的建立和銷燬問題。UI元件觀察LiveData,LiveData元件則觀察Lifecycle Owner。對各位Android 程式碼庫設計師們,我還有一點補充,你們可以使用完全相同的生命週期觀察程式碼,來為你自己的程式碼庫自動請求建立和銷燬方法。
ViewModel
現在還有一個問題需要解決,你的應用在執行期間,會經歷多種配置變化,這些變化會對Activity介面進行破壞和重建。我們不想把LiveData的初始化繫結在生命週期的Activity上,因為這會導致大量無用而重複的程式碼。這方面的一個例子就是資料庫查詢,每次你翻轉手機時,它都會被執行,那麼要怎麼辦呢?你把你的LiveData和任意其他與UI有關的資料放在ViewModel裡。
ViewModel 是一類為UI元件提供資料並能經歷多次配置更改而繼續存在的物件。建立ViewModel物件時,你需要繼承ViewModel
類,隨後把所有UI中必需的資料放進ViewModel中。
public class TrailListViewModel extends AndroidViewModel{
private AppDatabase mDatabase;
private LiveData<List<Trail>> trails;
public TrailListViewModel(Application application){
super(application);
//AppDatabase is a Room database singleton
//Check the guide for more information
mDatabase = AppDatabase.getDb(getApplication());
trails = mDatabase.trailModel().findAllTrails();
}
//Getters and setters
}
複製程式碼
因為你在ViewModel內部為UI快取了資料,所以如果你的Activity因為配置更改而被重新建立了,你的應用不會對資料庫進行查詢。隨後當你建立Activity或Fragment時,你就可以引用相應的ViewModel並使用它。
//In onCreate
trailListViewModel = ViewModelProviders.of(this)
.get(TrailListViewModel.class);
//Code to set up the RecyclerView omitted
trailListViewModel.getTrails().observe(this,trails ->{
mTrailsRectclerAdapter.replaceItems(trails);
mTrailsRectclerAdapter.notifyDataSetChanged();
}
複製程式碼
當你第一次得到ViewModel時,它是為你的Activity而生成的,當你再次請求ViewModel時,你的Activity會收到當初生成的ViewModel 和UI 快取資料。所以不會再有無用的資料庫呼叫了。
總結一下所有這些炫目的構建元件,我們談到了Room,這是一個為SQLite設計的物件處理庫。還有LiveData,它會在資料更改時通知你,這樣你就可以更新UI了。重要的是它和Room協作順暢,所以你可以在資料庫資料更改時,輕鬆更新UI。我們還談到了Lifecycle Observer 和Owner,他們可以讓非UI 物件觀察生命週期事件。最後我們還介紹了ViewModel,它會為你提供無法被配置更改破壞的資料物件。他們共同組成了一套構建元件,可以用來編寫模組化的、可測試的、強健的Android應用。你可以靈活地搭配運用它們,也可以挑選自己需要的來採用,但這些只是冰山一角而已。事實上,更加久經考驗的Android應用,看起來可能是這樣的: