Android ButterKnife Android 35情况下 适配 Gradle 8.+

Google play 最新上线要求 必须适配 targetSdk 35 七八年的老项目噩梦开始了

老项目升级开始

....

文档地址(官方)
developer.android.google.cn/google/play...

Google 的要求实际上是"连环硬性升级":

markdown 复制代码
targetSdk 35
    ↓
AGP 8.0+
    ↓
Gradle 8.0+
    ↓
JDK 17+

意味着你无法再用 JDK8,也无法继续沿用旧的 Annotation Processor 黑魔法,包括 ButterKnife。


2️⃣ 原项目与升级目标

当前老项目环境

  • targetSdk:33
  • Gradle:7.3.1
  • Kotlin:1.9.20
  • JDK:8

Google Play 适配目标

  • targetSdk:35
  • Gradle:8.2.0
  • Kotlin:1.9.20
  • JDK:17

升级带来的所有问题都来自下面两个:

❌ JDK 从 8 → 17

❌ Gradle 7 → 8(DSL 改动很大)


3️⃣ 升级后必做的配置调整

下面是升级 target35 + Gradle8 后所有必须改的点。

🔵 1. 必须声明 namespace(否则直接 build error)

Gradle 8 强制要求 module 中显式设置 namespace:

arduino 复制代码
android {
    namespace 'com.xxx.yyy'
}

如果不写,直接报错:

vbnet 复制代码
The namespace not specified. Please specify a namespace in the module's build.gradle file.

🔵 2. 必须显式开启 BuildConfig(否则找不到 BuildConfig)

Gradle 8 默认关闭 BuildConfig 生成。

arduino 复制代码
buildFeatures {
    viewBinding true
    buildConfig true
}

否则会出现经典报错:

arduino 复制代码
error: cannot find symbol class BuildConfig

🔵 3. 必须使用 JDK17(且全局一致)

你可能遇到这样一种"精神分裂"错误:

kotlin 复制代码
Unsupported class file major version 61

或:

makefile 复制代码
java.lang.NoSuchFieldException: classFile

原因是:

IDE 设置 JDK17,但系统 PATH 是 JDK8 → Gradle 还是调用 JDK8 → 直接炸。

必须保证:

  • Android Studio Gradle JDK = 17
  • 系统环境 JAVA_HOME = 17
  • 命令行 java -version = 17

不然各种奇怪报错乱飞。


4️⃣ 最致命部分:ButterKnife 在 JDK17 下完全炸裂

ButterKnife 是基于 Javac 内部 API 的 annotationProcessor,

而 JDK9+ 开始把这些内部 API 封死,JDK17 更是完全锁死。

于是你会看到这个大杀器报错:

ini 复制代码
Invalid argument: --add-opens=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED

或者:

makefile 复制代码
java.lang.ClassNotFoundException: com.sun.tools.javac.tree.JCTree

或更常见的:

vbnet 复制代码
warning: unknown enum constant ElementType.MODULE
error: cannot access com.sun.tools.javac.tree.JCTree

这些都是 JDK17 和 ButterKnife 的天然冲突。


5️⃣ ButterKnife 在 Gradle 8 + JDK17 的最终可用修复方案

官方已经不维护,但还能"强行续命"。

你需要加:


🔸 1. 老版本(最后一个)ButterKnife

去掉 项目目录中 build.gradle中的

classpath 'com.jakewharton:butterknife-gradle-plugin:10.2.3'

perl 复制代码
buildscript {
    dependencies {
        // classpath 'com.jakewharton:butterknife-gradle-plugin:10.2.3'
                }
        }

module 目录下保留

arduino 复制代码
implementation 'com.jakewharton:butterknife:10.2.3'
annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.3'

🔸 2. 必须关闭 nonFinalResIds

ButterKnife 编译依赖 final R.id.xxx

而 Gradle 8 默认是 non-final

强制设置: 在 gradle.properties 文件中添加

ini 复制代码
 nonFinalResIds = false

不然出现:

python 复制代码
error: id cannot be resolved or is not a field

🔸 3. 添加 Javac 打开模块的参数(核心 patch)

在模块 build.gradle 顶部/或尾部加入:

scss 复制代码
tasks.withType(JavaCompile).configureEach {
    options.fork = true
    options.forkOptions.jvmArgs += [            '--add-opens=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED',            '--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED',            '--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED',            '--add-opens=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED',            '--add-opens=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED',            '--add-opens=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED',            '--add-opens=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED',            '--add-opens=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED',            '--add-opens=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED',            '--add-opens=jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED'    ]
}

这一段的意思就是:

强行撬开 JDK17 的封印,让 ButterKnife 能继续访问内部 API。


6️⃣ 实际出现的报错总结(可加到博客)

升级过程中出现这些错误很正常:

① JDK8/17 混用导致

kotlin 复制代码
Unsupported class file major version 61

② namespace 未声明

arduino 复制代码
The namespace not specified. Please specify a namespace...

③ BuildConfig 未生成

arduino 复制代码
cannot find symbol class BuildConfig

④ ButterKnife 访问 Javac 内部 API 失败

ini 复制代码
Invalid argument: --add-opens=jdk.compiler/...
go 复制代码
error: cannot access com.sun.tools.javac.tree.JCTree

R.id 变 non-final 导致 ButterKnife 编译失败

python 复制代码
id cannot be resolved or is not a field

7️⃣ 最终总结:老项目升级 target 35 的通关地图

要想在不迁移到 ViewBinding 的情况下继续保留 ButterKnife,一个可行方案是:

  • AGP 8 + JDK17 是强制升级
  • ButterKnife 虽然官方不维护,但仍可通过 add-opens 暴力续命
  • Gradle 配置必须补齐 namespace、BuildConfig、nonFinalResIds
  • 全局 JDK17 一致性非常关键
  • kotlin 版本 1.7.20

相关推荐
千码君20163 分钟前
Trae:一些关于flutter和 go前后端开发构建的分享
android·flutter·gradle·android-studio·trae·vibe code
重生之我是Java开发战士3 小时前
【MySQL】事务 & 用户与权限管理
android·数据库·mysql
怣疯knight5 小时前
Windows不安装 Android Studio如何打包安卓软件
android·windows·android studio
ke_csdn5 小时前
从Java演变到Kotlin下的jet pack
android
wenzhangli76 小时前
在低代码设计中践行 Harness Engineering
android·低代码·rxjava
xingpanvip7 小时前
星盘接口开发文档:组合三限盘接口指南
android·开发语言·前端·python·php·lua
TechMix7 小时前
【fkw学习笔记】Android 13 AOSP 源码添加系统预置应用实战指南
android·笔记·学习
云起SAAS7 小时前
私域直播系统UniApp源码 多商户商城+直播带货 微信小程序+H5+安卓iOS
android·微信小程序·uni-app·私域直播系统
空中海8 小时前
01. 安卓逆向基础、环境搭建与授权
android
星河耀银海8 小时前
JAVA 泛型与通配符:从原理到实战应用
android·java·服务器