欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android開發(fā)Compose remember原理解析

 更新時間:2022年07月29日 11:43:38   作者:王可大蝦  
這篇文章主要為大家介紹了Android開發(fā)Compose remember原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

正文

看過Compose案例或者源碼的你,相信肯定是見過 remember 了的。顧名思義,Compose是要讓我們的代碼“記住”東西,那到底是記住什么呢?要是不 remember,相關(guān)功能就實現(xiàn)不了了嗎?

帶著這些問題,來一探究竟吧

隨機色文本

假設(shè)有這么一個“隨機底色文本”的需求:實現(xiàn)一個 Text,其背景色每次啟動都隨機產(chǎn)生,且生命周期內(nèi)不變

用Compose可以實現(xiàn)如下:

private val items = arrayOf(Color.Red, Color.Gray, Color.Magenta, Color.Blue, Color.Green, Color.Cyan)
@Composable
fun ColorText(name: String) {
    val color = items.random()
    val clicked = mutableStateOf(0)
    Log.d("ct", "ui compose")
    Column {
        Text(
            text = "I'm colored: ${clicked.value}", modifier = Modifier
                .padding(16.dp)
                .background(color)
                .clickable {
                    Log.d("ct", "clicked")
                    clicked.value = clicked.value + 1
                }
        )
    }
}

Text 調(diào)用 Modifier.background,設(shè)置隨機從items中取的顏色,每次新的啟動,都可能不一樣

然而很遺憾,上面的背景色雖然是隨機產(chǎn)生,但是單次生命周期里,就可能發(fā)生變化 —— 比如點擊一下文本,如下圖:

更奇怪的是,改變的 clicked 值,并沒有如預(yù)期一樣生效,一直是0……

現(xiàn)象和代碼不一?

原因分析

首先,上述代碼中的“點擊計數(shù)” clicked,僅僅是為了測試而存在。因為它是一個 MutableState 對象,點擊后改變其值,會觸發(fā)Recomposition流程,于是組件刷新。這樣一來,color 的值將重新由隨機函數(shù)算出,我們就看到背景色在變化了

同理,雖然我們好像在點擊的時候改變了 clicked 的值,希望像view系統(tǒng)一樣,界面直接響應(yīng)響應(yīng)。但是,因為Recomposition的存在,它又被重新構(gòu)造了,所以其值還是0

正確實現(xiàn)

要實現(xiàn)背景色的整個生命周期固定,但點擊文本后,點擊計數(shù)要更新,應(yīng)該這么做:

@Composable
fun ColorText(name: String) {
    val color = remember { items.random() }
    val clicked = remember { mutableStateOf(0) }
    //...
}

僅僅將color和clicked由 remember 包裹起來就解決了問題

remember的原理剖析

前面功能的實現(xiàn),全仗著remember的加持。它究竟是個啥?

我們先從顏色的remember著手,它調(diào)用的是這個:

@Composable
inline fun <T> remember(calculation: @DisallowComposableCalls () -> T): T =
    currentComposer.cache(false, calculation)

其注釋寫明了兩個關(guān)鍵點,這也是它的功能描述:

  • 記憶由calculation返回的值,僅在composition中執(zhí)行
  • 在Recomposition過程中,不會重新計算,而是直接返回第1步的值

那么這又是怎么做到的呢?

進一步的相關(guān)代碼:

@ComposeCompilerApi
inline fun <T> Composer.cache(invalid: Boolean, block: () -> T): T {
    @Suppress("UNCHECKED_CAST")
    return rememberedValue().let {
        // 無效或Empty值時,走if流程,計算并保存值,否則直接返回
        // remember傳入的invalid為false,所以肯定走值判斷
        if (invalid || it === Composer.Empty) {
            val value = block()
            updateRememberedValue(value)
            value
        } else it
    } as T
}
// 要么返回Composer.Empty ,要么返回傳給updateRememberedValue的值
@ComposeCompilerApi
fun rememberedValue(): Any?
// 更新調(diào)用rememberedValue()后的值,且此值在下一次調(diào)用rememberedValue()時返回
@ComposeCompilerApi
fun updateRememberedValue(value: Any?)
interface Composer {
    // ....
    companion object {
        /**
         * 用于標記無值的狀態(tài)
         */
        val Empty = object {
            override fun toString() = "Empty"
        }
    }
}

從上述代碼注釋中,基本上已經(jīng)對原理很清楚了,簡單地說就是:

  • 由composer作為存儲控制
  • 無值時,走初始化邏輯并返回值,同時存儲該值;有值時,直接返回已存儲的值

顏色的“值不變”清楚了,那點擊計數(shù)的“值變”又是怎么回事呢?

其實如出一轍,只是點擊計數(shù)remember的,不是普通值,而是一個 MutableState 類型。這樣一來,它就有兩層含義了:

  • MutableState對象本身在整個composition生命周期不變 —— 即類似普通值的狀態(tài)一致性
  • MutableState對象所存儲的實際值,可變 —— 這用以觸發(fā)Recomposition,并且獲取更新值

小結(jié)

remember 的存在,其實就是 Compose 機制下的產(chǎn)物,用以解決recomposition時的值恢復問題。而因為它的“值不變”特性,還可以用來解決耗時計算的問題,即,耗時計算被remember了,那它就只會執(zhí)行一次,避免了不必要的額外開銷

以上就是Android開發(fā)Compose remember原理解析的詳細內(nèi)容,更多關(guān)于Android開發(fā)Compose remember的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Android 圖片顯示與屏幕適配的問題

    Android 圖片顯示與屏幕適配的問題

    這篇文章主要介紹了Android 圖片顯示與屏幕適配的問題的相關(guān)資料,Android的分辨率問題是每個Android 開發(fā)者頭疼的問題,那么這里給大家介紹個萬能辦法,需要的朋友可以參考下
    2017-08-08
  • Android使用Handler實現(xiàn)倒計時功能

    Android使用Handler實現(xiàn)倒計時功能

    這篇文章主要為大家詳細介紹了Android使用Handler實現(xiàn)倒計時功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-06-06
  • Android ListView和Adapter數(shù)據(jù)適配器的簡單介紹

    Android ListView和Adapter數(shù)據(jù)適配器的簡單介紹

    這篇文章主要介紹了Android ListView和Adapter數(shù)據(jù)適配器的簡單介紹,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-04-04
  • Android保存Activity狀態(tài)的方法

    Android保存Activity狀態(tài)的方法

    這篇文章主要介紹了Android保存Activity狀態(tài)的方法,結(jié)合實例形式較為詳細的分析了Android保存Activity狀態(tài)的原理、實現(xiàn)步驟及相關(guān)注意事項,需要的朋友可以參考下
    2016-08-08
  • Android實現(xiàn)淘寶底部圖標導航欄

    Android實現(xiàn)淘寶底部圖標導航欄

    這篇文章主要為大家詳細介紹了Android實現(xiàn)淘寶底部圖標導航欄,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • Android開發(fā)中通過手機號+短信驗證碼登錄的實例代碼

    Android開發(fā)中通過手機號+短信驗證碼登錄的實例代碼

    最近在開發(fā)一個android的項目,需要通過獲取手機驗證碼來完成登錄功能,接下來通過實例代碼給大家分享手機號+短信驗證碼登錄的實現(xiàn)方法,需要的的朋友參考下吧
    2017-05-05
  • Android編程實現(xiàn)拍照功能的2種方法分析

    Android編程實現(xiàn)拍照功能的2種方法分析

    這篇文章主要介紹了Android編程實現(xiàn)拍照功能的2種方法,結(jié)合具體實例形式對比分析了Android通過調(diào)用系統(tǒng)攝像頭及程序調(diào)用照相機功能兩種實現(xiàn)技巧與相關(guān)注意事項,需要的朋友可以參考下
    2017-07-07
  • Android中Fragment的加載方式與數(shù)據(jù)通信詳解

    Android中Fragment的加載方式與數(shù)據(jù)通信詳解

    本文主要介紹了Android中Fragment的加載方式與數(shù)據(jù)通信的相關(guān)知識。具有很好的參考價值。下面跟著小編一起來看下吧
    2017-03-03
  • Android?Flutter中Offstage組件的使用教程詳解

    Android?Flutter中Offstage組件的使用教程詳解

    這篇文章主要為大家詳細介紹了Android?Flutter中Offstage組件的使用教程,文中的示例代碼講解詳細,對我們了解Flutter有一定的幫助,需要的可以參考一下
    2023-02-02
  • Android中使用Expandablelistview實現(xiàn)微信通訊錄界面

    Android中使用Expandablelistview實現(xiàn)微信通訊錄界面

    本文主要介紹了Android中使用Expandablelistview實現(xiàn)微信通訊錄界面(完善防微信APP)的方法,具有一定的參考價值,下面跟著小編一起來看下吧
    2016-12-12

最新評論