MVI架構
在Jetpack Compose官方介紹視頻里残腌,設計團隊提到Compose是基于MVI架構設計的,基礎架構演變從MVC、MVP净响、MVVM都是圍繞著View和Model關系來展開的,MVI也不例外白翻,如何“高內聚乍炉,低耦合”地進行程序設計是程序員永恒的命題。
我理解的MVI可以看做是“函數式編程思想”的一種表達形式滤馍,這和RX有點類似岛琼,整個View和Model的關系是以一種流式或者說響應式的方式進行組織的(也有點像大學里學習的《信號與系統》課程中對于信號的處理過程:input -> filter -> output),用戶輸入或者其他數據源的變更產生了一個Intent意圖(這是概念上的意圖巢株,和Android的Intent類沒什么關系)槐瑞,Model根據意圖輸出State狀態(tài),View根據State進行渲染阁苞。與傳統每個系統維護各自的狀態(tài)不同的是困檩,每一刻View的呈現都是根據Model的狀態(tài)來驅動的,即每次發(fā)生狀態(tài)的變化那槽,都擦掉整個畫布悼沿,重新根據Model產生的狀態(tài)進行渲染,這樣就去掉了View內部的狀態(tài)骚灸,保證View的渲染肯定對Model最準確的表達糟趾,Model到View的過程是函數式的,即無狀態(tài)的,View可以看做是一個filter义郑,固定的input就有固定的output蝶柿。ReactiveX其實最初的設計理念應該就是想將對事件的處理變成這樣一種無狀態(tài)的流式過程吧,雖然實際項目中更多的是將RX當做一種異步調度框架進行使用非驮。
這種每一次都擦除整個畫布的方式又和游戲開發(fā)中渲染過程很像交汤,整個世界是一個mainLoop,所有的變化都是通過每一次的update來完成的院尔,當我們決定怎么渲染這個世界后蜻展,渲染引擎就開始以流水線的方式運行,渲染管線Pipline經歷Vertex邀摆,Mesh纵顾, Rasterization等等階段,將邏輯數據經過點栋盹、線施逾、面、紋理例获、光照汉额、裁剪、柵格化等等流水線上每一個環(huán)節(jié)進行的處理最終形成了一張二維的畫面榨汤,給到屏幕去顯示蠕搜,每一幀都在重新畫一幅畫。
這種方式當也能更加直觀地以Declarative聲明式的方式進行編碼收壕,但每一次都重新繪制整個畫布的方式妓灌,在高效的GPU渲染管線上還好說(雖然也會用很多騷操作去優(yōu)化處理流程),放到CPU的邏輯計算階段代價就太大了吧蜜宪,我只是想更新一個文案虫埂,難道要整個布局重新繪制一次?所以一般采用這種方式進行設計的系統都需要在重繪的范圍上進行把控圃验,Jetpack Compose所謂的Recomposition重組的概念大概就是這么個事情吧掉伏,如何準確的識別狀態(tài)的變化,將重繪控制在最小的范圍內澳窑,就是整個Compose引擎的目的所在斧散。
Composable函數
@Composable
fun Greeting(name: String) {
Text(text = "Hello $name!")
}
Jetpack Compose的Hello World是以這樣一個Greeting開始的,關于Composable函數的幾點值得注意:
- @Composable注解和suspend關鍵字一樣是對函數類型的一個聲明照捡。
- Composable函數必須運行在Compose環(huán)境中颅湘。
- Composable函數是函數式的,即不產生返回值栗精,沒有Side Effect副作用闯参。
- Composable函數通過調用其他Composable函數以組合的方式進行工作瞻鹏,如上面這個函數中的Text也是一個Composable函數,會在頁面中渲染一個文本框鹿寨。
引用官方在Compose編程思想中所提到的對Composable函數的描述:
- 可組合函數可以按任何順序執(zhí)行新博。
- 可組合函數可以并行執(zhí)行。
- 重組會跳過盡可能多的可組合函數和 lambda脚草。
- 重組是樂觀的操作赫悄,可能會被取消。
- 可組合函數可能會像動畫的每一幀一樣非常頻繁地運行馏慨。
總結來講埂淮,Composable函數盡量去按照函數式編程的規(guī)范不產生side effect地去編寫,實際使用經驗還得通過項目實踐去感受呀写隶,期待Compose能早日實裝~
(以上是對Jetpack Compose不斷學習探索過程中的所想倔撞,只是我個人的一個筆記,持續(xù)學習記錄中慕趴,歡迎指正~)