為什麼 Android 堅持用 Intent 傳值:一個 API 習慣背後,是兩套記憶體哲學的帳
從 iOS 與 Android 兩套記憶體哲學的分歧,拆解 Intent 序列化傳值背後的系統設計成本結構,以及鴻蒙在兩者之間的取捨。
一篇發布於 2026 年 9 月 7 日掘金平臺的技術長文,近日在中國開發者社羣再度被轉引討論。文章的核心提問來自一批從 iOS 轉崗的工程師:為什麼 iOS 頁面之間可以直接用 Delegate 代理或閉包回傳結果,而傳統 Android 的 Activity 通信,卻要依靠 startActivityForResult 與 Intent 序列化打包這種看似笨重的方案。
這個問題表面是 API 使用習慣差異,實際攤開的是兩套作業系統對記憶體控制權的定價方式不同。iOS 把記憶體穩定視為前提假設,Android 則從第一行程式碼就把「元件隨時可能被殺死」寫進設計契約。
iOS 的前提:記憶體是穩定的資產
在 iOS 體系裡,應用頁面由 UINavigationController 統一管理。只要棧頂的 ViewController 存活,棧底各頁面就穩定駐留在同一個程序的堆記憶體中。物件生命週期完全可控,因此直接持有物件引用做回調,既高效又安全。這是 iOS 通信模型的基石假設:應用內記憶體不會被系統單方面回收。
這個假設有其硬體背景。iPhone 從初代起就走封閉硬體、單一晶片路線,記憶體配置由蘋果統一規劃,系統對背景程序的回收策略相對溫和。開發者拿到的是一個記憶體波動幅度較小的執行環境。
Android 的前提:元件預設無狀態
Android 誕生於 2008 年,早期行動裝置記憶體資源極度緊張,入門機種常見配置僅 512MB 甚至更低。為保障前景應用體驗,系統服務 ActivityManagerService 擁有最高權限:一旦記憶體喫緊,可以隨時殺死背景的任意 Activity。這意味著應用自身無法保證 Activity 物件一定存活。
文章模擬了一個經典場景來說明後果。頁面 A 打開頁面 B,使用者接到電話,系統記憶體壓力升高,背景的頁面 A 被銷毀,頁面 B 仍在前景運行。使用者完成操作返回時,若頁面 B 直接持有頁面 A 的介面物件指標,呼叫 callback.onResult() 的當下,原始 A 物件已不存在,回調指標沒有可接收結果的宿主,直接觸發空指標異常甚至崩潰。
關鍵認知在於,問題的層次高於「怕崩潰」。物件引用的語義已經徹底失效,B 手中的指標指向一個已經消亡的物件。記憶體控制權不在開發者手上,共享記憶體引用這條通信路徑在系統層面就不成立。
消息驅動:Token 取代指標
Android 的 Activity 元件從設計上就預設了兩種可能性:隨時可能被系統回收銷毀,以及支援跨應用、跨程序被拉起。因此它不依賴共享記憶體物件引用做通信,而是採用消息驅動設計。Android 三大基石,Intent、Binder、Bundle,全部傳遞序列化消息,不傳遞記憶體物件引用。
startActivityForResult 正是為應對元件隨時重建而誕生的協議。頁面 A 不傳遞物件引用,僅傳入一個 requestCode 作為通信標識;頁面 B 關閉時,把結果封裝進 Intent 與 Bundle,交由系統中轉。就算頁面 A 先前已被殺死,系統會重新建立 A,再把序列化完成的資料交付給 onActivityResult。
底層本質是:系統只儲存 Token、requestCode 這類標識,不儲存任何 Java 物件引用。onActivityResult 因此並非普通函式回調,而是系統分發的生命週期事件。開發者付出的序列化成本,換到的是跨程序與跨生命週期的通信保證。這是一筆用執行效率換生存能力的交易。
演進:Activity Result API 補的是工程債
onActivityResult 解決了元件重建後的資料恢復問題,但代價清楚可見。程式邏輯分散在發起與接收兩處,requestCode 魔法數字容易衝突,多個請求需要大量條件分支,耦合度高。
Google 後來在 Jetpack 推出 Activity Result API,即常用的 registerForActivityResult。值得注意的是,這次改版改的是開發者側的介面形態,把分散的邏輯收攏、把魔法數字換成型別安全的合約物件,底層仍然是序列化消息中轉那一套。框架演進沒有推翻消息驅動假設,只是降低它的使用成本。這與平臺技術替代的一般規律相符:架構層的取捨一旦寫進系統契約,後續迭代多半是包裹更好的糖衣,而非推倒重來。
鴻蒙的位置:兩套哲學之間的折衷
該文另一個被廣泛摘錄的段落,是對鴻蒙(HarmonyOS)設計取捨的分析。鴻蒙的頁面單元 Ability 同樣支援跨裝置遷移,序列化傳值的必要性與 Android 同源。差異在於鴻蒙在宣告式 UI 與狀態管理框架上做得更激進,試圖在系統層面把狀態恢復的成本從開發者身上挪走。這與我們先前追蹤的鴻蒙生態全球化戰略屬於同一條主線:一個作業系統要爭取開發者,降低通信與狀態管理的工程成本是第一道門檻。類似的訊號也出現在電信設備端,高通在 6G 路線圖中把 AI 原生與智慧體終端寫進系統定義,顯示「讓系統承擔更多狀態管理責任」已經是跨平臺的共同方向。
收束判斷
回到最初的問題。iOS 開發者覺得 Intent 笨重,帳要這樣算:iOS 的記憶體穩定是蘋果用封閉硬體與單一裝置策略買來的;Android 面對的是記憶體從 512MB 到 16GB 跨越三十餘倍的裝置碎片化市場,加上跨程序拉起元件的需求,物件引用通信在系統層面就不成立。序列化成本是 Android 為裝置覆蓋廣度支付的固定費用。
判斷一個 API 設計的優劣,先看它為誰的最佳化。Delegate 與閉包為單一程序內的開發效率最佳化,Intent 為跨程序、跨生命週期的生存能力最佳化。兩者帳本不同,直接比較語法輕重,比錯了欄位。
主題