Skip to content
This repository was archived by the owner on Sep 22, 2026. It is now read-only.

Releases: IamCanincan/HardCrop

v1.0.9 — 修复第三方应用闪退 + 手动运维按钮 + 界面整理

Choose a tag to compare

@IamCanincan IamCanincan released this 21 Sep 18:27

⚠️ 如果你正在用 v1.0.8,请立刻升级到 v1.0.9 —— v1.0.8 会导致部分第三方应用启动即崩溃。

修复:第三方应用闪退

现象:某些第三方应用冷启动时直接闪退、反复崩溃,清图标缓存也没用。

报错:

android.content.res.Resources$NotFoundException: Resource ID #0x6e08013b
    at android.content.Context.getDrawable
    at com.android.internal.widget.ActionBarView.setIcon
    at android.app.Activity.initWindowDecorActionBar
    at ...MainActivity.onCreate

根因:模块给应用图标的资源 ID 打标记(0x7f… → 0x6e…),好在图标加载出口认出它并裁成圆形。但打标记发生在 system_server(PMS)里,这些对象随后会经 Binder 传给任意应用进程。接收方不在本模块作用域内(没有还原逻辑)时,拿到的伪造 ID 在它自己的资源表里根本不存在,一解析就抛异常 —— 而调用点就在 Activity.onCreate 里,于是直接把应用带崩。

修复:在 writeToParcel(Binder 序列化出口)统一把标记还原成合法的 0x7f…,彻底掐断跨进程泄漏。已注入的进程(桌面 / 设置 / 状态栏等)收到后仍会重新打标记,裁圆功能不受影响。

修复:桌面图标的「全出血」开关从未生效

与同类模块逐条对齐排查时发现:IconOptions.drawFullBleed 是装箱的 java.lang.Boolean,而代码里写的是 Field.setBoolean() —— 它只接受基本类型 boolean,对装箱字段会抛 IllegalArgumentException。

模块跑在保护模式下,这个异常被整个吞掉:既不崩溃、也不留任何日志。结果是这个开关从加入那天起就没起过作用,真机日志里累计抛出了 9994 次。

已改为 Field.set()(自动拆箱,基本类型与装箱类型都成立)。修好后桌面图标不会再带多余的黑色方角,而且每次生成图标都少一次异常开销。

真机验证:清缓存全量重建后裁圆 40/40;新进程之后该异常 0 次。

新增:手动运维按钮(界面「运维操作」一栏)

  • 清除缓存并重启桌面 —— 删掉桌面的 app_icons.db 并重启桌面,图标按当前逻辑重新生成
  • 重启 SystemUI
  • 重启其他进程(设置 / 设置建议 / 意图解析器 / 权限控制器)

这几个动作全部由模块在目标进程内部完成(删自己的缓存、重启自己),不需要 root,也不会执行任何 shell 命令。

同时按反馈移除了自动清缓存:什么时候清由你决定,模块不再自作主张删除桌面的数据库。

界面整理

  • 加了顶部应用栏(随列表滚动收起),右上角可直接打开仓库。
  • 分区标题与卡片重新分组,一眼能看出标题领着哪张卡。
  • 作用域列表默认只展开「必选 + 推荐」,5 条「可选」折叠起来,页面短了近一半。
  • 验证命令改成整块点击复制(原来只有右侧一个小图标能按);按钮圆角统一。

真机验证

  • 华为应用市场冷启动不再崩溃,进程正常存活(修复前连续两次 FATAL EXCEPTION)。
  • 另测 Kimi / TapTap / Mihon 三个不在作用域的第三方应用,均无崩溃。
  • 桌面清缓存后重建:裁圆调用 40/40(日志预算打满),覆盖自适应图标与位图图标,无回归。
  • 三个运维按钮均实测生效(桌面 29273→29395 并重建图标、SystemUI 29918→30239、设置进程被杀后重新注入)。
  • 界面在真机逐项确认:顶栏、作用域展开/收起、三个运维按钮均渲染正常,滚动与切换无崩溃。
  • assembleRelease + lintDebug 均 0 error 0 warning。

说明

  • 不需要额外权限,也不需要 root。
  • 若你之前因为闪退在 LSPosed 里取消勾选了某些应用,升级后可以重新勾选。

HardCrop v1.0.8

Choose a tag to compare

@IamCanincan IamCanincan released this 21 Sep 14:26

⚠️ 此版本会导致部分第三方应用启动即崩溃,请立即升级到 v1.0.9。

(问题:模块给图标资源 ID 打的标记会跨进程泄漏到未注入的应用,解析时抛异常并直接带崩应用。)


变更

  • 模块更新 / 启用后自动清理 launcher3 图标缓存:升级后桌面不会再显示上一版渲染的方形图标,无需手动操作(每个模块版本只清一次)
  • 强制圆形裁切现已覆盖全部界面:桌面 / 抽屉、最近任务、设置应用列表、分享页、冷启动开屏、状态栏、权限弹窗、数字健康、电池用量页、主题图标(动态取色)
  • 覆盖进程(作用域不写死,可在 LSPosed 管理器自行勾选):system_server、systemui、launcher3(含 Pixel Launcher)、settings、分享页、权限控制器、数字健康等 10 个
  • 自适应图标同样强制裁圆,并透传 monochrome 层以支持 Android 13+ 主题图标染色

校验

  • SHA256:8fa0fed3d1ae4930d275c3869a212ba34258fcb105e12394e2489072c3a39b3b
  • 包名 com.iamcanincan.hardcrop,versionCode 8 / versionName 1.0.8

HardCrop v1.0.4

Choose a tag to compare

@IamCanincan IamCanincan released this 21 Sep 08:26

变更

  • 修复应用列表不裁切:图标内容改放在 background 层,RoundedIconDrawable 用 DST_IN 自裁正圆(不再依赖系统 mask,解决 Settings 应用列表等直绘页面仍是方形的问题)。
  • 对齐参考项目通道:覆盖 global-icon-pack-android 的全部图标加载通道(严格超集),并保留双 ThreadLocal 防重入(marking + replacing),避免同一条调用链上圆套圆 / 尺寸重复缩放。
  • 新增裁圆专属通道:Settings.Utils.getAdaptiveIcon(deoptimize)、电池用量页、冷启动 splash、APM.getDrawable / getApplicationIcon 等直接 Drawable 出口。
  • 去除临时诊断探针,行为稳定。

适用

LSPosed / LibXposed(API 102)。把非自适应图标强制裁成圆形。

HardCrop v1.0.3

Choose a tag to compare

@IamCanincan IamCanincan released this 20 Sep 16:25

修复

  • 修点击桌面图标导致桌面崩溃(v1.0.2 的严重 bug,装了 1.0.2 请尽快升级)
    点击桌面 / 抽屉里任意非自适应图标的 app,会让桌面(launcher)整个进程崩溃闪退。
    根因:CircleIconDrawable.getConstantState() 返回了 null,而 Launcher3 的
    FloatingIconView 会直接 icon.getConstantState().newDrawable() —— 拿到 null 就是 NPE。
    现在包装类与其内层都实现了 getConstantState() 且永不返回 null。

  • 适配 Pixel Launcher(com.google.android.apps.nexuslauncher)
    Pixel / Nexus 的桌面进程包名跟类原生 ROM 用的 com.android.launcher3 不一样,
    之前模块不会作用于它。现在作用域列表、内部类(BaseIconFactory / IconOptions)
    查找、以及应用内的作用域清单都同时兼容这两个包名。

已知限制

  • 设置页 / 分享菜单里的应用列表项,走的是 system_server 里 PMS 缓存的 Bitmap,
    而 system_server 在开机时往往早于 LSPosed daemon 启动、未被注入,这一处看到的
    仍是原图。重启一次设备可让 system_server 也进入注入。
  • 点击图标时桌面的浮起过渡动画,其图标外框由 launcher 自己绘制,本模块不介入。
  • 快捷设置磁贴画的是小尺寸单色图形,通知栏小图标走别的资源,均不受影响。

校验

SHA256  ad14dc0916dda1034444408a97d71445acb9d674734b8dae6401763ecbb48d78
size    1076927 bytes

HardCrop v1.0.2

Choose a tag to compare

@IamCanincan IamCanincan released this 20 Sep 14:59

把非自适应图标强制裁成圆形 —— 只做这一件事。已经是自适应图标的应用不会被改动。

安装

  1. 需要 root + LSPosed(或其兼容框架,libxposed API 100+)。
  2. 装好下面的 APK,在 LSPosed 里启用模块。
  3. 重启设备 —— 模块不支持热加载。

作用域已经用 staticScope 固定为 6 个进程,管理器里只能勾这些,勾别的会被框架拒绝:

android                         系统服务,解析应用信息
com.android.launcher3           桌面与应用抽屉(效果最直观)
com.android.systemui            状态栏与最近任务
com.android.settings            设置里的应用列表
com.android.intentresolver      分享与打开方式的选择列表
com.android.permissioncontroller 权限弹窗里的应用图标

至少勾选 com.android.launcher3 才能在桌面看到效果。

验证

adb logcat -s HardCrop

看到 onPackageReady 与 Hooked 就说明模块已注入该进程。

本次包含的改动

1.0.2 是本仓库的第一个 Release,包含了自 1.0 以来的全部改动:

  • 包名统一为 com.iamcanincan.hardcrop,并补上应用界面(作用域清单、启用步骤、
    验证命令、检查更新)。之前纯后台模块没有桌面图标,只能去设置的应用列表里找。
  • 静态作用域:scope.list 只留模块真正 hook 的 6 个进程。
  • 模块描述:改用 android:description(管理器读的是 ApplicationInfo.descriptionRes;
    写在 module.prop 的 description= 是 API ≤ 93 的旧写法,LibXposed 不读)。
  • 检查更新:应用内唯一联网行为,且只在点了按钮之后才发起。先直连 GitHub,
    连不上时退到公共加速镜像。没有统计也没有上报。
  • Android 16+:额外关掉 Pixel Launcher 自带的白色圆形背景板
    (IconOptions.drawFullBleed = false),图标按原样铺满圆形。

已知取舍

  • 快捷设置磁贴画的是单色小图形,被排除在外。
  • 旧版 Android(< 16)的桌面会保留 launcher 自带的背景板,模块只能保证 Drawable 本身是圆形。
  • 应用列表(Settings)走 PMS 的 Bitmap 缓存,重启后才会刷新;桌面与应用抽屉即时生效。

校验

SHA256  d30ae06dd3c084d0afaca048f99da2032e83fd9326e80569ed1b0cd459e75da3

MIT 许可。