☰
Canta 实战指南:基于 Shizuku 与 ADB 的免 Root Android 卸载与去臃肿方案
2026/10/10 2:42:15 网站建设 项目流程
  • 移动开发

【免费下载链接】Canta

Uninstall any Android app without root (with power of Shizuku). Debloat your device as you wish, with Android app or even from your browser!

项目地址:https://gitcode.com/gh_mirrors/ca/Canta
点击查看免费下载

Canta 是一个面向 Android 9.0+(SDK 28+)的开源去臃肿工具,它借助 Shizuku 特权运行时在完全不需要 root的情况下卸载预装应用与用户应用,并集成 Universal Debloat List 提供安全卸载建议。本文以仓库 README.md 为主线,结合 CantaHandler.kt、PackageOperations.kt 等源码,完整讲解它的三种使用形态(Android 应用、桌面端、浏览器端)、上手步骤以及底层的 Shizuku + 隐藏 API + ADB Helper 实现原理,读完即可在自己的设备上安全完成卸载与恢复。

Canta 是什么:核心能力与设计理念

Canta 的核心定位在 README 的 About 一节中表述得非常明确:uninstall pre-installed or user apps without root(无需 root 卸载预装应用与用户应用),其能力要点包括:

  • ✅无需 root:通过 Shizuku 特权运行时获得受限系统权限,而不是获取完整的 root 权限;
  • ✅检测已卸载应用:即使跨应用重装,Canta 依然能识别出哪些应用曾被它卸载;
  • ✅支持 Android 9.0+(SDK 28+);
  • ⚠️不会"永久变砖",但可能 bootloop:如果卸载了关键系统应用,可能导致开机循环,只能通过恢复出厂设置解决;
  • ⚠️部分 oplus 应用(Oppo/OnePlus 等)比较顽固,拒绝被卸载(仓库跟踪问题见 README 注释)。

从架构上看,"无需 root"的能力并不是黑魔法,而是通过特权运行时 + 隐藏 API 绕过的组合实现的。仓库中用 CantaHandler.kt 定义了一个统一的处理程序契约:

  • loadApps():读取已安装应用以及"为当前用户卸载但仍在设备上"的应用;
  • loadIcons():以 Flow 流式返回应用图标;
  • uninstallApps(packageNames, resetToFactory):按包卸载,可选先将更新过的系统应用重置回出厂版本;
  • reinstallApps(packageNames):重新安装之前卸载的应用;
  • packageExists()/openAppDetails():包存在性检查与打开系统应用详情页。

这个接口在每个目标平台都有独立实现:Android 走 Shizuku,桌面走 ADB(dadb),Web/WASM 走 WebUSB(ya-webadb)。也就是说,同一套 Compose 多平台 UI 可以同时驱动手机、PC 和浏览器三种去臃肿入口,这是 Canta 区别于绝大多数同类工具的最大特点。

三种使用形态与平台架构

README 提供了三张下载渠道徽章(F-Droid、IzzyOnDroid、GitHub Releases)和 Play Store 入口,实际使用形态有三种:

形态设备连接方式特权来源核心实现
Android 应用(APK)本机Shizuku / SuiAndroidCantaHandler.kt
桌面端(Desktop)USB 数据线 + ADB设备上的 ADB Helper(shell 用户)AdbCantaHandler.kt + DesktopCantaHandler.kt
浏览器端(Web/WASM)USB 数据线 + Chromium 内核浏览器设备上的 ADB Helper(shell 用户)WebCantaHandler.kt + WebAdbTransport.kt

README 特别强调:"不想下载安装?只要有数据线和 Chromium 内核浏览器,可以直接在网页端使用 Canta,无需安装任何东西。"网页端入口由 webApp/src/wasmJsMain/kotlin/io/github/samolego/canta/main.kt 启动,通过 Compose 的ComposeViewport挂载到页面的cantaApp容器中,复用与 Android 完全相同的 CantaApp.kt 界面。

设备发现机制的差异

设备的选择方式在不同平台上差异很大,这一点在 CantaHandler.kt 的DeviceDiscovery枚举中体现:

  • None:始终是本地设备(Android 上通过 Shizuku),无需选择;
  • List:Canta 自己列出可连接的设备(桌面端通过 ADB);
  • SystemPicker:由系统选择器授权并选择设备(Web 端通过 WebUSB 选择器)。

同时,DeviceConnectionFailure密封接口把连接失败原因细分成了AccessDenied(携带UsbAccessHint,用于提示 Linux udev 规则或 Windows WinUSB 驱动问题)、DeviceBusy、DeviceUnavailable、HelperUnavailable、UnsupportedAndroidVersion、UnsupportedBrowser等,UI 层可以据此给出精确的修复建议,而不是笼统的"重新插拔"。

快速上手:三步完成卸载(How-to)

README 的 How-to 一节给出了最简洁的三步流程,这里逐条展开并补充细节:

第 1 步:安装并激活 Shizuku

  1. 从 Play Store 安装 Shizuku(应用包名moe.shizuku.privileged.api);
  2. 按 Shizuku 官方 setup 指南激活它(常见方式:无线调试配对 / USB 调试 +adb shell sh /sdcard/Android/data/moe.shizuku.privileged.api/start.sh);
  3. 需要更深入说明可参考社区图文教程(README 中推荐了 Android Police 的 Shizuku 指南);
  4. 注意:README 明确指出,Android 16 上可能需要使用 Shizuku 的 fork 版本(thedjchi/Shizuku),因为官方版本在 Android 16 上的兼容性尚不完善。

激活完成后,Canta 会检测 Shizuku 的运行状态。在 CantaHandler.kt 中定义了PrivilegeStatus枚举来描述四种状态:

  • ACTIVE:特权运行时正在运行且 Canta 已获得授权;
  • NOT_AUTHORIZED:运行时在跑,但尚未授权 Canta;
  • NOT_RUNNING:运行时已安装但服务未启动;
  • NOT_AVAILABLE:没有安装特权运行时(桌面/Web 端恒为该状态)。

当状态不是ACTIVE时,界面会弹出 ShizukuRequirementDialog 引导用户处理(Android 端与 ADB 端各有一套实现,位于 dialog 和 dialog.adb 目录)。

第 2 步:安装 Canta

从 F-Droid、IzzyOnDroid、GitHub Releases 或 Play Store 下载 APK 并安装。为验证下载文件的真实性与完整性,README 提供了用于校验的SHA-256 证书指纹:

0A:26:40:31:7C:43:27:21:88:C3:E1:31:94:C1:54:60:69:1F:12:C3:9E:A1:9B:BA:72:7D:D6:7F:B5:62:89:D4

可使用keytool -printcert -jarfile canta.apk或sha256sum等工具对 APK 签名/哈希进行核对后再安装。

第 3 步:选择应用并卸载

打开 Canta,在应用列表中选择要卸载的应用,点击垃圾桶按钮(FAB),确认后即完成"为当前用户卸载"。需要恢复时,切到"已卸载"列表,选中并点击恢复按钮即可。

这一步的背后是 MainViewModel.kt 中的完整操作序列:授权(authorize)→ 确认(confirm)→ 生物识别认证(authenticate)→ 执行卸载/恢复(uninstall/reinstall)。其中生物识别认证由 CantaPlatform.kt 的requireBiometric提供,Android 上会弹出系统级指纹/凭据提示;桌面与 Web 端没有生物识别能力,会直接回调onSuccess。

值得一提的是,Canta 不允许卸载自身:MainViewModel中在用户选中包名等于CANTA_PACKAGE_NAME(io.github.samolego.canta)时会弹出提示并中止操作,避免用户误删导致无法再管理设备。

桌面与浏览器端:ADB Helper 的工作模式

桌面端和 Web 端并非直接调用 Android 的 PackageManager,而是通过ADB 在设备上拉起一个 helper 进程来执行所有包操作。helper 的入口是 helper/src/main/kotlin/io/github/samolego/canta/helper/Main.kt,其启动方式在注释中有明确说明:

CLASSPATH=<apk> app_process /system/bin io.github.samolego.canta.helper.Main <command>

app_process运行在 shell 用户下,可以访问完整的 Android framework,因此标签名、图标读取与 Android 本机版完全一致。该 helper 支持以下命令:

命令作用
info返回一个PackageDetailsList,包含设备上所有已安装与已卸载(for user)的包
icons <sizePx>以显示顺序逐个流式返回每个包的 PNG 图标(AppIcon消息)
uninstall [--reset] <package>...每个包卸载完成后输出一条OperationResult
reinstall <package>...每个包恢复完成后输出一条OperationResult
version输出PROTOCOL_VERSION(当前为 3,见 PackageDetails.kt)

行协议:base64 编码的 protobuf

helper 与客户端之间的通信协议在 HelperFraming.kt 中定义:每条消息 = 一行 base64 编码的 protobuf,写往 stdout;诊断信息走 stderr,保证 stdout 只承载协议数据。选择文本行分帧而非原始二进制,是因为部分 ADB 传输(如 ya-webadb 的spawnWaitText)只能返回解码后的文本,原始二进制会被破坏。

协议消息体用 kotlinx-serialization-protobuf 定义,字段编号一旦发布即不可重编或复用(PackageDetails的注释明确警告这一点)。核心消息包括:

  • PackageDetails:包名、label、版本名/版本号、是否禁用、APK 体积(base + split)、是否系统应用、是否为当前用户安装、是否有系统更新覆盖;
  • PackageDetailsList:协议版本号 + 包列表;
  • AppIcon:包名 + PNG 字节;
  • OperationResult:包名 + 成功标志 +PackageInstaller.STATUS_*状态码 + 消息。

连接建立与失败兜底

桌面/Web 端连接设备后,AdbCantaHandler.onConnected()会依次做两件事:先用helper.supportsDevice()检查设备 Android 版本是否满足要求(过旧则报UnsupportedAndroidVersion),再调用helper.ensureInstalled()把 helper APK 推送到设备并校验(失败则报HelperUnavailable)。任何一步失败,客户端都会主动断开连接。这样设计保证了一旦进入应用列表,所有后续操作都可执行,而不是半途而废。

卸载与恢复的底层原理

隐藏 API + PackageInstaller

所有卸载/恢复操作最终都落在 PackageOperations.kt。它通过SystemServices.service("package")拿到系统IPackageManager的 binder,再绕过隐藏 API 限制调用隐藏的PackageInstaller.uninstall(packageName, flags, statusReceiver)与IPackageInstaller.installExistingPackage(...)。

关键的隐藏常量(源码中有注释标注):

  • DELETE_ALL_USERS = 0x00000002:普通用户应用使用,为所有用户卸载;
  • DELETE_SYSTEM_APP = 0x00000004:系统应用使用;
  • INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS = 0x00400000:恢复安装时使用;
  • INSTALLER_PACKAGE = "com.android.shell":安装器身份,getMySessions会校验安装器 owner(ADB 下即 shell)。

awaitStatus会用一个LocalIntentSender作为状态接收器,等待最多 30 秒(RESULT_TIMEOUT_MS)的安装器回调,并把EXTRA_STATUS/EXTRA_STATUS_MESSAGE包装成OperationResult。若超时无状态返回,会再检查包的实际安装状态兜底(STATUS_NO_RESULT时"包已不存在/已恢复"也计为成功)。整个方法被reportingFailure包裹:任何异常(隐藏 API 缺失、binder 死亡等)都会转换为单包失败结果,不会中断整个批处理队列。

resetToFactory:更新过的系统应用怎么卸载

对"带更新覆盖的系统应用"(canResetToFactory == true,即isSystem && hasSystemUpdate),uninstall(..., resetToFactory = true)会执行两阶段卸载:

  1. 第一次带DELETE_SYSTEM_APP的卸载只移除系统更新,把应用还原为出厂版本;
  2. 第二次卸载才真正移除出厂版本本身。

源码注释对此有明确解释:"for system apps, the firstDELETE_SYSTEM_APPuninstall only removes the update, the second then uninstalls the factory version."即使第一次重置失败,代码也只记录警告并继续尝试卸载,保证操作可继续推进。

为什么能"检测已卸载应用"并能恢复

Canta 所谓的卸载,本质是uninstall for user(为当前用户卸载),而不是彻底删除 APK。应用仍然留在设备存储中,因此:

  • getAllPackages()(见 PackageManagerExt.kt)能同时枚举出已安装与"已卸载但仍在"的包,PackageDetails.installed字段区分两者——这就是 README 所说"Detects previously uninstalled apps (even across reinstalls)"的机制;
  • 恢复时调用IPackageInstaller.installExistingPackage直接基于设备上保留的副本重新安装,无需重新下载 APK;
  • 列表排序由 PackageDetails.kt 的inDisplayOrder()决定:已安装应用在前、已卸载在后,各自按显示名(label,无 label 时取包名最后一段)字母序排列;没有 label 的包用displayName兜底显示。

安全注意事项与免责声明

README 的开头即用醒目的警告框声明:

DISCLAIMER:⛔ Use at your own risk. I am not responsible for any data loss or damage caused by this app ⛔.

结合 README 与源码,使用 Canta 需要明确以下边界:

  1. 可能 bootloop:卸载关键系统应用可能导致开机循环,届时只能恢复出厂设置;Canta 的机制只是"为当前用户卸载",并不能保证所有设备厂商的应用都允许卸载;
  2. oplus 应用例外:部分 Oppo/OnePlus 应用"很顽固,不允许卸载",这是已知限制而非 bug;
  3. 权限边界:Android 端依赖 Shizuku 授权,授权后 Canta 以 shell/系统权限操作 PackageInstaller;请只从可信渠道下载 APK 并核对上文 SHA-256 指纹;
  4. 自我保护:Canta 禁止卸载自身,避免用户把管理工具本身误删后无法恢复设备;
  5. 卸载可逆:得益于"uninstall for user"设计,已卸载应用可通过 Canta 恢复,无需联网重装。

项目结构速览与延伸阅读

  • README.md:项目介绍、下载渠道、使用三步与免责声明(本文主体);
  • composeApp:Compose 多平台 UI 与业务逻辑(commonMain 共享,androidMain/adbMain/wasmJsMain/desktopMain 分平台实现);
  • packages:包管理核心库,包含 PackageOperations.kt、HelperFraming.kt 与协议模型;
  • helper:ADB 端 on-device helper 的入口(Main.kt);
  • hiddenApiStubs:用于编译时引用隐藏 API 的 stub(IPackageManager.java、IPackageInstaller.java);
  • metadata/en-US/images/phoneScreenshots:官方界面截图,与 docs 目录下的使用文档互相印证;
  • 翻译协作通过 Crowdin 进行,仓库根目录的 crowdin.yml 定义了多语言资源映射,各语言字符串位于composeApp/src/commonMain/composeResources/values-*/strings.xml。

如需从源码开始探索,可执行git clone https://gitcode.com/gh_mirrors/ca/Canta获取仓库副本,然后按gradle/libs.versions.toml中的依赖版本在 Android Studio 或命令行中构建各目标。

小结

Canta 用一套 Compose 多平台代码同时支撑了手机(Shizuku)、桌面(ADB)与浏览器(WebUSB)三条去臃肿路径:Android 端通过 Shizuku + 隐藏 API 直达 PackageInstaller,桌面/Web 端则借助app_process拉起的 ADB Helper 以 base64-protobuf 行协议完成同样的操作。它的"卸载即 uninstall-for-user"设计让操作可逆、跨重装可检测,是日常去系统臃肿时兼顾安全性与便利性的实用工具。使用前请务必核对 SHA-256 指纹,并牢记对关键系统应用的操作风险。

  • 移动开发

【免费下载链接】Canta

Uninstall any Android app without root (with power of Shizuku). Debloat your device as you wish, with Android app or even from your browser!

项目地址:https://gitcode.com/gh_mirrors/ca/Canta
点击查看免费下载
上一篇:PyO3 多版本 Python 支持指南:利用 pyo3-build-config 的条件编译与运行时版本检测
下一篇:komorebi 的 container-padding 命令:按工作区精确控制容器内边距

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询