ByteScope

pm trim-caches

會改變裝置

要求系統一直丟掉快取檔案,直到剩下你指定的空間為止。

指令
adb shell pm trim-caches
指令
套件(pm)
風險
會改變裝置

語法

pm trim-caches <free space target>[K|M|G]

旗標與參數

token意義
<target>希望留下的空間。後綴是 1024 的次方,所以 `512G` 是 512 GiB,比任何手機都大——這是「把你願意丟的都丟掉」的寫法。

範例

  • pm trim-caches 512G

    把系統認為可丟的快取全部釋放。

  • pm trim-caches 2G

    空間到 2 GiB 就停。

輸出怎麼讀

什麼都沒有。成功就是沒有輸出:它等平台做完,然後什麼都不印就返回,而且它不會回報釋放了多少——連「有沒有釋放到東西」都不會說。唯一誠實的「幫你空出 N MB」是用 `df` 或 `dumpsys diskstats` 前後各量一次。只要有任何輸出就是拒絕:後綴不合法、少了數字,或這個版本沒把所需權限給 shell 而拋出例外。

輸出欄位

欄位意義
(no output)trim 執行了。釋放多少不會回報。
Invalid suffix: …大小參數看不懂。
Error: expected number at: …大小參數不是數字。

需要什麼權限

一條授權過的 `adb` 連線,其他都不用:`android16-release` 分支的 `packages/Shell/AndroidManifest.xml` 宣告了 `CLEAR_APP_CACHE`,正是 `freeStorageAndNotify` 檢查的那個權限。不用 root、不用 `adb root`、沒有開發人員選項要開,也沒有逐個 app 的授權。有意思的是這個權限買不到什麼。`runTrimCaches` 帶著 `StorageManager.FLAG_ALLOCATE_DEFY_ALL_RESERVED` 呼叫 `freeStorageAndNotify`,在觀察者上等到它做完,然後回傳 0,從頭到尾沒看過 `obs.result` 一眼——shell 使用者被允許問,但永遠不會被告知答案。整份拒絕的版本還是看得出來,因為外層印出的例外會打破「安靜等於成功」這條規則;但一個給了權限卻什麼都沒釋放的版本,和釋放了一 GB 的版本長得一模一樣。前後各量一次剩餘空間——Android Storage Analyzer 就是這樣做的——是唯一能拿到誠實數字的路。

失敗訊息對照

訊息意義
Invalid suffix:`runTrimCaches` 自己解析大小參數,遇到不認識的後綴就印這個,後面接著你打的字。什麼都沒 trim。乘法也在同一個解析器裡,而它算的是 1024 的次方,所以就算後綴它收,意思也可能和硬碟廠商講的不一樣。
Error: expected number at:參數根本不是數字——最常見的是參數順序寫反,或延續 `pm clear` 的習慣在指令後面打了套件名稱。什麼都沒跑。跟這裡每一種拒絕一樣,判斷方式很簡單:這個指令印出了任何東西。
Exception occurred while executing 'trim-caches':外層抓到從 `freeStorageAndNotify` 丟出來的 `Throwable` 並倒出堆疊追蹤;沒把 `CLEAR_APP_CACHE` 給 shell 使用者的版本就是這一類。`classifyTrimCaches` 把所有非空輸出都當成拒絕,而在「成功本身沒有任何正面訊號」的情況下,這是唯一安全的讀法。

會改變什麼,以及怎麼回頭

刪的是快取檔,不是使用者的資料:帳號、存檔、下載內容都不會動,每個 app 下次啟動時會自己重建需要的東西。沒有什麼需要還原的,也沒有指令能還原——回頭的路就是繼續使用那些 app,快取自然會補回來。你會感覺到的是代價:快取補回來之前,app 開啟與重新載入會比較慢。而且這個指令不會回報釋出了多少,要知道請在前後各用 `df` 或 `dumpsys diskstats` 量一次剩餘空間。

版本與廠商注意事項

  • 決定什麼可丟的是系統而不是你。哪些 app 的快取會被丟、依什麼順序丟,都是這個指令無法影響的平台政策。
  • 後綴按 1024 的次方解讀,所以 `1G` 是 1 GiB 而不是 1 000 000 000 個位元組。

這個我們有 UI

Android Storage Analyzer 會透過 USB 執行這個指令並解析回應——只要 Chromium 系瀏覽器,不必安裝 SDK,也不會上傳任何東西。

開啟 Android Storage Analyzer

相關指令

和 pm trim-caches 會在同一次作業裡出現的指令。

指令做什麼
pm clear清除某個 app 的資料——在 Android 13 之後也可以只清快取。
dumpsys diskstats每個分割區的剩餘空間、一次磁碟寫入延遲的實測,以及一份快取起來的各 app 空間用量。
df回報每個已掛載檔案系統的剩餘與已用空間。
du回報一棵目錄樹占掉多少磁碟空間。

其他套件(pm)指令

指令做什麼
pm list packages列出已安裝的套件,也能一次帶出 APK 路徑、uid、版本碼與安裝來源。
pm path印出組成某個已安裝套件的 APK 檔絕對路徑。
pm uninstall移除套件,或只針對一個 Android 使用者移除——這是不用 root 也能處理掉預載 app 的方法。
pm disable-user在不移除的前提下,把套件對某個 Android 使用者關掉——比解除安裝安全,而且確定能還原。
pm install安裝一個已經在裝置上的 APK,也就是 `adb install` 底層在做的事。
pm install-create開一個安裝工作階段,讓 base 與它的 split 作為一個不可分割的整體一起安裝。

這些行為是在撰寫 Web ADB 工具背後的解析程式時,對照 AOSP、toybox 與核心原始碼查證的。真的會因 Android 版本或廠牌而異的地方,這一頁會直接說明,而不是給你一個在半數手機上都是錯的數字。

常見問題

adb shell 指令要怎麼執行?

在手機上打開開發者選項與 USB 除錯、接上線,然後從裝了 platform-tools 的機器執行 adb shell <指令>——或者只執行 adb shell 取得互動提示字元,再直接打指令、不用前綴。如果指令會輸出二進位資料(例如截圖),請改用 adb exec-out 而不是 adb shell:單純的 shell 服務會配一個終端機,而它會改寫換行位元組並毀掉資料。

adb shell 指令需要 root 嗎?

這份參考裡的都不用。它們以 shell 使用者身分執行,可以針對自己的 Android 使用者管理套件、讀取大多數 dumpsys 服務、寫入設定提供者、注入輸入,以及讀取共用儲存空間。需要 root 的是這份參考刻意避開的事:讀取其他 app 的私有資料(除了對可除錯版本使用 run-as)、寫入系統分割區,或直接讀 /data/anr。

為什麼在我的手機上輸出看起來不一樣?

不是 Android 版本就是廠商。有些旗標與欄位是從特定版本才有的,那些都在各指令頁註明了。其餘是廠商改動,而受影響最深的是 dumpsys:一份 dump 是除錯輸出,它的文字就是那個服務的作者最後印了什麼,而廠商既會改它也會把改動往回移植。請用名稱而不是位置來讀欄位,並把沒見過的格式當成差異而不是失敗。

可以用瀏覽器而不是終端機來跑嗎?

很多指令可以——本站的 Web ADB 工具從 Chromium 系桌面瀏覽器透過 WebUSB 和手機對話,不必安裝 SDK,也不會上傳任何東西。每一頁在有對應工具時都會連過去。有兩個限制值得知道:同一時間只有一個程式能持有 ADB 介面,所以桌面的 adb server 要先停掉;而 adb forward 與 adb reverse 在瀏覽器裡完全無法運作。

比較想按而不是打字?Web ADB Toolkit 會從瀏覽器透過 USB 執行這類指令。或者瀏覽全部指令。