
高通 QM215 的原生 Android 10 BSP 剛編譯出來,開機什麼 App 都沒開就吃掉 1.3GB RAM。
在 2GB 的破板子上,剩下的 700MB 要塞 950MB 的雙鏡頭串流與 300MB 的 AI 模型,物理上直接爆炸。
我們做的是 7×24 小時掛在牆上的專用門禁機,不是手機。它不需要音樂、通話、輸入法,甚至連電池都沒有。
瘦身不能無腦拿鋸子亂改 Java 源碼。我們分兩階段動刀:先走 AOSP 原廠標準規範,再依門禁機物理特性極限抽脂。
第一階段:AOSP 工業界標準規範(零侵入瘦身)
Google 與晶片廠對低記憶體設備早有標準規範,一行 Java 代碼都不用改:
1. 繼承 Google go_defaults.mk(Android Go 模式)
在產品 device.mk 開頭引入:
# 引入 Android Go 輕量化配置
$(call inherit-product, build/make/target/product/go_defaults.mk)
底層自動生效 ro.config.low_ram=true,關閉多視窗、動態桌布與視窗陰影,並將背景快取進程上限從 32 壓到 3 個。
2. 在 BoardConfig.mk 宣告 TARGET_NO_TELEPHONY := true
門禁機沒有 SIM 卡與 4G 模組,直接由編譯系統剔除基頻:
TARGET_NO_TELEPHONY := true # 拔除 RIL 與通話 Daemon
TARGET_NO_RADIO := true # 關閉射頻通訊
BOARD_HAVE_BLUETOOTH := true # 保留藍牙 (BLE)
3. 移除 permissions/*.xml(讓 SystemServer 自然跳過)
SystemServer 啟動服務前會檢查 pm.hasSystemFeature()。只要在 device.mk 中不把對應 XML 複製到 /system/etc/permissions/,服務就不會實體化:
- 移除
android.hardware.nfc.xml:NfcService 不啟動。 - 移除
android.software.print.xml:PrintManager 不啟動。 - 移除
android.hardware.telephony.xml:TelephonyRegistry 不啟動。 - 移除
android.hardware.location.gps.xml:LocationManager 忽略 GPS。
第二階段:門禁機專屬的極限 Kiosk 抽脂(再榨 220MB)
走完標準規範後系統降至 1.0GB。接著針對「固定在牆上、插電運作、單一全螢幕 App」的特性剔除剩餘贅肉:
1. 幹掉 SystemUI 與 Launcher3(省 80MB ~ 120MB)
- 人臉辨識 App 的
AndroidManifest.xml宣告為HOME,開機直達全螢幕,省去 Launcher3(省 40MB):<category android:name="android.intent.category.HOME" /> <category android:name="android.intent.category.DEFAULT" /> config.xml關閉 Keyguard 鎖屏(省 15MB):<bool name="config_enableLockScreen">false</bool>
2. 拔除 LatinIME 輸入法(省 25MB ~ 35MB)
門禁機不需要虛擬鍵盤,PIN 碼由 App 內自繪。從 PRODUCT_PACKAGES 剔除 LatinIME,並在 config.xml 關閉:
<bool name="config_showDefaultIME">false</bool>
3. 拔除電池監控(省 15MB + 省 CPU 輪詢)
門禁機接 12V 變壓器或 PoE,沒有鋰電池。關閉 PowerUI 低電量警告,屬性寫死 ro.boot.charger=0,避免系統輪詢電量與維護電池日誌。
4. 禁用 Zygote 預載 WebView(省 30MB ~ 50MB)
人臉辨識為純 Native/OpenGL 渲染。修改 ZygoteInit.java 跳過 WebViewFactory.prepareWebViewInZygote(),不讓進程分裂時繼承 Chromium 內核。
5. 裁剪音訊特效與無用 Codec(省 20MB)
清空 /vendor/etc/media_codecs.xml 裡的 Dolby/DTS/4K 解碼外掛,停用 audioserver 音效處理器,只留 PCM 嗶聲與 TTS。
6. 鎖死螢幕旋轉與單用戶(省 15MB)
設備鎖死在牆上,build.prop 設定 fw.max_users=1,並鎖定方向 persist.sys.app.rotation=force_land(或 portrait),關閉陀螺儀輪詢。
理智的底線:必須誓死捍衛的命根子
- BLE 藍牙協議棧(GATT Server):保留供工程師現場免插線配網與金鑰派發。
- Wi-Fi 與 Ethernet(netmgrd):特徵庫離線同步與 WebSocket 推送必備。
- thermal-engine:高通溫控守護,防止晶片在密閉機殼內過熱降頻或燒毀。
- surfaceflinger / inputflinger:相機預覽與螢幕渲染核心。
戰果驗收:記憶體帳單
- 原生高通 Android 10 BSP:開機常駐 1,300 MB
- 第一階段(Go 模式 + 拔通話 + 特性裁減):降至 1,000 MB(省 300 MB)
- 第二階段(Kiosk 極限裁減:Launcher/IME/電池/Webview):再降至 ~780 MB(省 220 MB)
- 最終優化後系統常駐:780 MB(淨奪回 520MB 實體 RAM)
在 2GB RAM 的低配機上,我們為雙鏡頭串流(950MB)與 AI 模型(300MB)留出了超過 1.2GB 的純淨實體空間,徹底告別 OOM。
結語
- 先走標準規範:善用
go_defaults.mk、TARGET_NO_TELEPHONY與 Feature Flags 完成體制內瘦身。 - 再依場景裁減:針對門禁機「無桌面、無輸入法、無電池、純 Native」特性剔除剩餘贅肉。
這才是真正的系統級工程治理。
參考資料 (References)
- Android Go Edition Device Configuration: Google 官方 Android Go 低記憶體規範.
https://source.android.com/docs/core/perf/low-ram - AOSP System Features & Permissions: Managing system features via permission XMLs.
https://source.android.com/docs/core/permissions/perms-features - Android Enterprise Dedicated Device (Kiosk Mode): Single-app device deployment guidelines.
https://developer.android.com/work/dpm/dedicated-devices

發佈留言