深入瞭解 GetX 的 Obx 與 Rx

更新於 發佈於 閱讀時間約 7 分鐘


最近在做畫面時,滿常使用 GetX 的 Obx + Rx 變數,讓畫面可以根據狀態變化即時更新。過程中有時會碰到一些錯誤,在建置 Widget 的過程中,因為 Obx 找不到可以被監聽的目標,導致 Obx 認為使用者錯誤的使用了 Obx,所以透過 Exception 來提醒使用者。

raw-image

Obx 的使用方法是把一個 builder 方法傳給 Obx 這個 Widget,不需要任何 Rx 變數做為參數。像是下面的這個簡單的 count 例子中,Obx 傳入一個 builder 方法,只要 builder 在建置 Widget 的過程中使用 Rx 變數,Obx 就能進行監聽。

raw-image

這就讓我自己十分好奇,Obx 到底是如何找到 builder 方法中的 Rx 變數,然後對這個 Rx 變數進行監聽呢?自己花了一些時間研究和實驗,今天就來分享一下,到底 GetX 中的 Obx 是如何完成他的工作的。

兩位主角

在 Counter 例子中,有兩個重要的物件,一個是 Obx,另一個則是存放 count 的 Rx 變數。其中 Obx 身上有一個型態為 RxNotifier 的 _observer 變數,主要用來監聽 Rx 變數並更新畫面的。而存放 count 的 Rx 變數的爺爺也是 RxNotifier。

raw-image

RxNotifier 本身沒有任何實作,實作都是集中 NotifyManager 這個 mixin 身上。NotifyManger 身上主要有兩個方法

  1. addListener:用來決定監聽什麼事件
  2. listen:用來決定監聽到事件後,要做什麼事

Obx 如何更新畫面

當開始 build GetCountView 的畫面並 build 到 Obx 時,程式會先執行 ObxWidget initState() 方法。在 initState() 中執行 _observer.listen,並傳入 _updateTree,讓 _observer 監聽到事件時,可以呼叫 setState 更新畫面。

raw-image

再來程式會走進 ObxWidget 的 build 方法。可以發現 ObxWidget 的 build 方法也就只是轉頭呼叫 RxInterface 的 notifyChildren 靜態方法,並傳入 ObxWidget 身上的 _observer 和 widget.build

raw-image

此時的 widget.build 也就是我們在 GetCountView 中傳給 Obx 的那段印出 count 的 builder。

raw-image

當我們在深入 RxInterface.notifyChildren 之後,可以發現在程式會把 ObxWidget 身上的 _observer 塞到一個全域變數 RxInterface.proxy 中。然後繼續執行 builder 並 build 出顯示 count 數的 Text Widget。最後把 RxInterface.proxy 還原成原本的值,然後就回傳結果了。

raw-image

看到這邊好像還是不知道 Obx 到底是如何發現 builder 之中的 RxInt 的,我們只有看到 _observer 被賦予了他要觸發 setState 的工作,但是 _observer 是如何監聽 count 事件呢?

在 Getter 中註冊監聽

其實關鍵就在 builder 中。我們回頭看一下使用 Obx 那段程式碼,Text 中使用了 count.value,而關鍵就在這個 value getter 中。

raw-image

讓我們深入看一下 value 這個 getter 是如何被實作的。

raw-image

在使用 value getter 時,程式會向 RxInterface.proxy 這個全域變數註冊一個 subject,還記得先前 RxInterface.notifyChildren 做了什麼嗎,它把 ObxWidget 身上的 _observer 塞給 RxInterface.proxy,此時 value getter 中用的對象就是 ObxWidget 身上的 _observer。最後,當 value 發生變化時, Rx 變數就會透過 subject 通知 _observer。

簡單來說,Obx 與 Rx 變數是透過 RxInterface 這個全域變數作為橋樑,讓兩者可以在 build 的時候建立觀察者模式。當 Rx 變數透過 value setter 賦值時,就能成功通知 ObxWidget 身上的 _observer,_observer 接收到事件之後就觸發 setState(),讓畫面根據新的狀態更新。

整理流程

  1. GetCounterView 開始建置,隨後呼叫 ObxWidget 的 build 方法
  2. ObxWidget 的 build 方法被呼叫後,轉頭直接把工作轉交給 RxInterface.notifyChildren,並且傳入 _observer 與 builder
  3. RxInterface 先是把 _observer 放進 RxInterface.proxy 中
  4. RxInterface.notifyChildren 呼叫 builder,建置 builder 中的 Widget
  5. builder 在建置的過程中會使用 count 這個 Rx 變數取得 count 值
  6. 取得 count 值過程中,Rx 也會呼叫 RxInterface.proxy?.addListener,讓 _observer 可以監聽

raw-image

ps. 實際上並不是由 GetCountView 直接呼叫 ObxWidget.build 的,這邊只是簡化一下呼叫流程。實際上是由 GetCountView 的 Element 去呼叫的。

小結

GetX 作為熱門的 Flutter 狀態管理套件之一,有許多容易使用的 API,其中也大量的使用全域變數 。使用的時候還需要多加考慮一下,用得太多容易導致產品程式碼與套件緊緊相依,不只測試難寫,想抽換狀態管理的套件也會十分麻煩,使用的時候需要多多思考。

分享各種軟體開發技巧與心得
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
本系列文章聚焦 Flutter 開發中常見問題,如畫面開發、狀態管理與 API 呼叫,結合 SOLID 等設計原則,提供實用解法與優缺點分析,幫助讀者選擇合適方法。透過 DartPad 範例,讀者可實際執行、修改程式碼,加深理解設計理念,提升開發效率與程式碼品質。
這篇文章說明在 Flutter App 中整合 Google Play 內購功能的流程。主要包含兩個部分:先在 Google Play Console 設定商品,然後使用 Flutter 的 in_app_purchase 套件實作購買功能。開發時需注意連線狀態、商品列表獲取,以及購買流程的實作。
本系列文章聚焦 Flutter 開發中常見問題,如畫面開發、狀態管理與 API 呼叫,結合 SOLID 等設計原則,提供實用解法與優缺點分析,幫助讀者選擇合適方法。透過 DartPad 範例,讀者可實際執行、修改程式碼,加深理解設計理念,提升開發效率與程式碼品質。
這篇文章說明在 Flutter App 中整合 Google Play 內購功能的流程。主要包含兩個部分:先在 Google Play Console 設定商品,然後使用 Flutter 的 in_app_purchase 套件實作購買功能。開發時需注意連線狀態、商品列表獲取,以及購買流程的實作。
你可能也想看
Google News 追蹤
Thumbnail
隨著理財資訊的普及,越來越多台灣人不再將資產侷限於台股,而是將視野拓展到國際市場。特別是美國市場,其豐富的理財選擇,讓不少人開始思考將資金配置於海外市場的可能性。 然而,要參與美國市場並不只是盲目跟隨標的這麼簡單,而是需要策略和方式,尤其對新手而言,除了選股以外還會遇到語言、開戶流程、Ap
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
上個月根據民法的修正,「正向教養」這個詞又被再度拿出來討論了一番... 在現代育兒的洪流中,「正向教養」已成為許多家長耳熟能詳的名詞,但它究竟是什麼?如何在日常生活中落實?本文將帶您深入了解正向教養的核心理念,以及如何透過實際方法,為孩子建立既溫暖又有界限的成長環境。
Thumbnail
扁平足是一種常見的足部問題,其特徵是足弓較平坦。這可能由先天性或後天性因素造成,並可能引起足部疼痛、疲勞、腫脹及鞋子磨損異常。為減少不適,建議維持健康體重、選擇合適鞋子、加強足部肌肉及使用矯正鞋墊。專業醫師可透過觀察及檢查來確診扁平足問題。瞭解其成因與解決方案,有助於更好地管理此狀況。
Thumbnail
本文深入探討 NoSQL 資料庫的特性及優勢,並將其與傳統 SQL 資料庫進行比較。NoSQL 資料庫因其結構靈活、擴展性強而適合儲存變化多端的數據,特別是在社交媒體和電商平臺等高需求場景。CAP 理論也被提出,解釋了分散式系統的能力取捨問題,幫助讀者瞭解在不同需求下如何選擇合適的資料庫技術。
Thumbnail
本篇文章將幫助讀者深入瞭解人工智慧(AI)的基本概念及其涉及的多項重要技術,包括機器學習、深度學習、類神經網絡等關鍵詞。透過對這十個關鍵詞的系統解析,讀者能夠掌握AI的基礎,進而展開對AI領域的深入學習。文章鼓勵讀者留言提問,以便獲得更直接的解釋,助力AI學習之旅。
本文探討 Amazon CloudFront 的熱門物件報告,分析近7天和近30天總位元組數的差異,解釋為何在不同時間範圍內,熱門物件清單可能會不同。報告依賴於持續追蹤請求數,以確保數據的可靠性,並提供精確的物件使用情況。透過數據的解讀,幫助用戶優化內容分發策略。
就是指變數可以被訪問和使用的範圍,來說一下var、let和const的作用域差異。 var :function example() { console.log(x); // 輸出: undefined 因為變量提升造成的 var x = 5; } 函數作用域或全域作用域 可以重複宣告
Thumbnail
本文介紹了在網站開發中如何運用狀態機的原則和設計方法。通過具體案例分析,以及狀態和數據的區分,詳細介紹了狀態機的設計原則和應用。讀者可以通過本文瞭解如何將狀態機應用於實際的網站開發中。
Thumbnail
在網路速度有限的情況下,依序記錄不斷產生的資訊,能統計使用者在頁面上操作了哪些功能。
Thumbnail
瞭解如何在Xcode15及以上使用Logger進行更好的程式debug。Logger可以更好的組織Log,但也有一些缺點需要注意。本文將介紹Logger的基本使用方式,以及一些注意事項。
Thumbnail
需求情境: 在設計畫面時,資料來源是後台的 api,每一次畫面細節的修修改改,都會觸發 Xcode Preview 程序,導致不斷呼叫後台。此時若資料結構和大小都具有一定規模,就會導致效率低落,不斷等待,且消耗伺服器資源甚鉅。 解決方案: 將後台傳回的資料以檔案形式暫存在本地端,每次 pr
Thumbnail
隨著理財資訊的普及,越來越多台灣人不再將資產侷限於台股,而是將視野拓展到國際市場。特別是美國市場,其豐富的理財選擇,讓不少人開始思考將資金配置於海外市場的可能性。 然而,要參與美國市場並不只是盲目跟隨標的這麼簡單,而是需要策略和方式,尤其對新手而言,除了選股以外還會遇到語言、開戶流程、Ap
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
上個月根據民法的修正,「正向教養」這個詞又被再度拿出來討論了一番... 在現代育兒的洪流中,「正向教養」已成為許多家長耳熟能詳的名詞,但它究竟是什麼?如何在日常生活中落實?本文將帶您深入了解正向教養的核心理念,以及如何透過實際方法,為孩子建立既溫暖又有界限的成長環境。
Thumbnail
扁平足是一種常見的足部問題,其特徵是足弓較平坦。這可能由先天性或後天性因素造成,並可能引起足部疼痛、疲勞、腫脹及鞋子磨損異常。為減少不適,建議維持健康體重、選擇合適鞋子、加強足部肌肉及使用矯正鞋墊。專業醫師可透過觀察及檢查來確診扁平足問題。瞭解其成因與解決方案,有助於更好地管理此狀況。
Thumbnail
本文深入探討 NoSQL 資料庫的特性及優勢,並將其與傳統 SQL 資料庫進行比較。NoSQL 資料庫因其結構靈活、擴展性強而適合儲存變化多端的數據,特別是在社交媒體和電商平臺等高需求場景。CAP 理論也被提出,解釋了分散式系統的能力取捨問題,幫助讀者瞭解在不同需求下如何選擇合適的資料庫技術。
Thumbnail
本篇文章將幫助讀者深入瞭解人工智慧(AI)的基本概念及其涉及的多項重要技術,包括機器學習、深度學習、類神經網絡等關鍵詞。透過對這十個關鍵詞的系統解析,讀者能夠掌握AI的基礎,進而展開對AI領域的深入學習。文章鼓勵讀者留言提問,以便獲得更直接的解釋,助力AI學習之旅。
本文探討 Amazon CloudFront 的熱門物件報告,分析近7天和近30天總位元組數的差異,解釋為何在不同時間範圍內,熱門物件清單可能會不同。報告依賴於持續追蹤請求數,以確保數據的可靠性,並提供精確的物件使用情況。透過數據的解讀,幫助用戶優化內容分發策略。
就是指變數可以被訪問和使用的範圍,來說一下var、let和const的作用域差異。 var :function example() { console.log(x); // 輸出: undefined 因為變量提升造成的 var x = 5; } 函數作用域或全域作用域 可以重複宣告
Thumbnail
本文介紹了在網站開發中如何運用狀態機的原則和設計方法。通過具體案例分析,以及狀態和數據的區分,詳細介紹了狀態機的設計原則和應用。讀者可以通過本文瞭解如何將狀態機應用於實際的網站開發中。
Thumbnail
在網路速度有限的情況下,依序記錄不斷產生的資訊,能統計使用者在頁面上操作了哪些功能。
Thumbnail
瞭解如何在Xcode15及以上使用Logger進行更好的程式debug。Logger可以更好的組織Log,但也有一些缺點需要注意。本文將介紹Logger的基本使用方式,以及一些注意事項。
Thumbnail
需求情境: 在設計畫面時,資料來源是後台的 api,每一次畫面細節的修修改改,都會觸發 Xcode Preview 程序,導致不斷呼叫後台。此時若資料結構和大小都具有一定規模,就會導致效率低落,不斷等待,且消耗伺服器資源甚鉅。 解決方案: 將後台傳回的資料以檔案形式暫存在本地端,每次 pr