Skip to content

fix(semi-icons): 用框架属性替代未定义的 ?attr/colorControlNormal - #35

Open
Windsland52 wants to merge 1 commit into
Aliothmoon:mainfrom
Windsland52:fix/semi-icons-framework-colorcontrolnormal
Open

Windsland52 wants to merge 1 commit into
Aliothmoon:mainfrom
Windsland52:fix/semi-icons-framework-colorcontrolnormal

Conversation

@Windsland52

Copy link
Copy Markdown
Contributor

Fixes #34

问题

semi-icons 的 484 个 drawable 都写着:

android:tint="?attr/colorControlNormal"

但本模块没有 dependencies {}(不依赖 appcompat),模块内也没有任何地方定义 colorControlNormal。AGP 对库模块会单独做一次资源链接,此引用在库自己的资源图里解析不到,于是:

Execution failed for task ':semi-icons:verifyReleaseResources'.
> Android resource linking failed
  ERROR: .../drawable/ic_semi_alarm.xml:9: AAPT: error: resource attr/colorControlNormal
         (aka com.aliothmoon.maafw.semiicons:attr/colorControlNormal) not found.

在 app 层这个引用是合法的(app 依赖 appcompat),所以只要任务图里没有库模块自己的 assembleRelease,问题就完全不可见:

命令 :semi-icons:verifyReleaseResources
./gradlew :app:assembleRelease(IDE Build APK / Generate Signed APK) 不在任务图里
./gradlew assembleRelease(根目录,CI 用法) 在任务图里 → 必失败

改动

484 个 drawable 的 tint 换成框架属性:

android:tint="?android:attr/colorControlNormal"

android:attr/colorControlNormal 自 API 21 起存在,minSdk 28 安全;不引入新依赖,保持"纯资源模块"的定位。可替代方案是给模块加 implementation(libs.androidx.appcompat),但会把 appcompat 拖进一个只放图标的模块,故未采用。

验证

  • ./gradlew :semi-icons:verifyReleaseResourcesBUILD SUCCESSFUL
  • ./gradlew clean assembleRelease(根目录,即 CI 的命令)→ BUILD SUCCESSFULverifyReleaseR8Keeps 通过(8 个关键类保留),arm64-v8a release APK 正常产出
  • aapt2 dump xmltree 对比同一图标:旧包 tint 解析为 ?0x7f03005d(appcompat 的 colorControlNormal),修改后为 ?0x01010429android:attr/colorControlNormal),AppCompat 主题下取值一致

需要注意

semi-icons/build.gradle.kts 注释里写着资源由 scripts/extract_semi_icons.py 生成,但该脚本不在本仓库中,生成器需要同步改为框架属性,否则重新生成图标会把这个引用写回来、问题复发。

(另外建议:本问题只在根目录 assembleRelease 下暴露,如果 release 校验想更早发现,可以考虑在 CI 里跑库模块的 assembleRelease 而不只是 :app:assembleRelease。)

484 个图标 drawable 的 android:tint 引用的是应用命名空间的
colorControlNormal,但本模块既不依赖 appcompat 也没定义该属性,AGP 对库
模块单独做资源链接时必然失败:

    :semi-icons:verifyReleaseResources
    AAPT: error: resource attr/colorControlNormal
          (aka com.aliothmoon.maafw.semiicons:attr/colorControlNormal) not found

app 层因为依赖 appcompat、主题是 Theme.AppCompat.DayNight 能解析该引用,
所以 IDE / 单模块 :app:assembleRelease 一直正常,只有根目录
./gradlew assembleRelease(会命中所有模块的 assembleRelease)才会把这个
校验带进任务图,缺陷因此长期潜伏。

改用框架属性 ?android:attr/colorControlNormal:API 21 起一直存在,
minSdk 28 安全,不引入依赖,app 侧语义不变。

注意 scripts/extract_semi_icons.py 不在本仓库中,生成器需同步改为框架属性,
否则重新生成图标会复发。

Refs Aliothmoon#34
@Windsland52

Copy link
Copy Markdown
Contributor Author

顺带一个跟这次修复配套的建议(不阻塞合并):仓库现在没有 CI(没有 .github 目录),所以这类"只有 release 路径才会踩到"的问题没有任何自动拦截。

一条命令就够,不需要 NDK / keystore / agent 运行时:

# .github/workflows/library-resources.yml
name: Verify library resources

on: [push, pull_request]

jobs:
  verify:
    runs-on: ubuntu-latest
    timeout-minutes: 20
    steps:
      - uses: actions/checkout@v7
      - uses: actions/setup-java@v5
        with:
          java-version: "25"
          distribution: temurin
      - uses: android-actions/setup-android@v4
      - run: ./gradlew verifyReleaseResources

几点说明:

  • 根项目没有同名任务时,Gradle 会命中所有库模块(当前是 :hidden-api:semi-icons),以后新增库模块自动纳入。
  • 任务图只有 16 个资源类任务(generateReleaseResources / mergeReleaseResources / processReleaseManifest / verifyReleaseResources),本地实测 4~8s,冷启动一两分钟;不需要 NDK、CMake、keystore、Python 或 agent 运行时。
  • gradlew 本身是 100755,不需要 chmod

这个 PR 修的 bug 正好是这类:把 484 个图标里的1 个改回 ?attr/colorControlNormal 后,:semi-icons:assembleDebug 成功、verifyReleaseResources 失败——也就是 IDE / app-only 出包和 debug 路径都拦不住它,只有根目录 assembleRelease 才会红。

如果暂时不想加 CI,退一步的做法是发版前手工跑一次根目录的 ./gradlew clean assembleRelease(覆盖最全,但要 NDK/keystore,比较重),至少不会把问题留到 tag 上才发现。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[bug] :semi-icons:verifyReleaseResources 失败:drawable 的 android:tint 引用 ?attr/colorControlNormal 在库模块内未定义

1 participant