2025-10-04 10:00:00
升级 Android targetSDK 至 35 并使用 Gradle 8.0+ 后,遇到了第三方库 namespace 配置问题。
1 2 3 4 |
|
或者类似错误:
1 2 3 4 5 |
|
Android Gradle Plugin 8.0+ 不再支持在 AndroidManifest.xml
中通过 package
属性设置 namespace,要求在 build.gradle
中显式声明。升级 targetSDK 至 35 需要使用 Gradle 8.0+,但很多第三方库(如 react-native-inappbrowser
、appcenter-analytics
等)尚未更新配置,导致构建失败。
在项目根目录的 android/build.gradle
文件中添加以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
|
此方案包含三个层次的处理:
project.group
并将点号替换为下划线作为 namespacebuildConfig
特性AndroidManifest.xml
中提取 package
属性build.gradle
作为 namespace
AndroidManifest.xml
中的 package
属性这个 task 在每次构建前(preBuild
)自动执行,确保所有第三方库都符合 Gradle 8.0+ 的要求。
build.gradle
和 AndroidManifest.xml
文件node_modules
中生效,不影响源码仓库执行以下命令重新构建项目:
1 2 3 |
|
或在 React Native 项目中:
1
|
|
构建过程中会看到类似输出:
1 2 |
|
如果只需要为缺少 namespace 的库自动设置默认值,可以使用简化版:
1 2 3 4 5 6 7 8 9 10 11 |
|
简化方案不会修改任何文件,仅在内存中设置 namespace,但可能无法解决所有第三方库的问题。
2025-09-28 08:56:00
在 Flutter 开发过程中,很多开发者遇到一个困扰的问题:当使用终端运行 flutter run
命令进行开发时,一旦关闭 Android Studio 或 IntelliJ IDEA,终端中的 flutter run
进程就会自动结束,导致应用停止运行。本文将详细分析这个问题的原因并提供解决方案。
flutter run
启动 Flutter 应用flutter run
进程自动结束,应用停止运行flutter run
进程当 Android Studio 启动时,它会自动管理 ADB(Android Debug Bridge)服务器的生命周期。默认情况下,IDE 会:
这种设计导致即使是通过终端独立启动的 flutter run
进程,也会因为 ADB 服务器的关闭而被迫结束。
1
|
|
当 Android Studio 关闭时,它管理的 ADB 服务器也会关闭,进而导致所有依赖该 ADB 连接的进程(包括终端的 flutter run
)都被终止。
最有效的解决方案是让 Android Studio 使用外部手动管理的 ADB 服务器,而不是自己管理一个实例:
Build, Execution, Deployment
→ Debugger
Android Debug Bridge (adb)
部分Adb Server Lifecycle Management
中选择 Use existing manually managed server
Existing ADB server port
为 5037
(默认端口)这样配置后,Android Studio 不会在启动时接管 ADB 服务器,也不会在关闭时终止它,从而保证终端运行的进程不受影响。
配置完成后,可以通过以下步骤验证:
flutter run
flutter run
是否依然运行如果 flutter run
进程没有被终止,说明配置成功。
通过配置 Android Studio 使用外部手动管理的 ADB 服务器,可以有效解决 IDE 关闭后终端 flutter run
进程自动结束的问题。这种方法的优势在于:
推荐所有 Flutter 开发者采用这种配置方式,特别是那些习惯在终端中运行 flutter run
的开发者。
2025-06-24 10:30:00
排查日志时,常需要定位关键字并带上一两行上下文确认语义。grep
内建的上下文选项可以直接满足需求,不必再手动 sed -n '19,21p'
。
假设想在 app.log
中找出包含 Fatal error
的行,并且同时看到上一行与下一行:
1
|
|
-n
会显示行号,便于定位。-C 1
等价于 --context=1
,表示向前向后各多带 1 行。想多看几行时调整数字即可。输出中,命中的行以冒号分隔行号与内容,上下文行则以短横线 -
连接,快速区分重点。
grep
提供三个粒度化参数:
-C <N>
:两侧各 N 行,是最常用的形式。-B <N>
:只带前 N 行(Before)。-A <N>
:只带后 N 行(After)。例如只关心关键字后面的调用栈,可使用:
1
|
|
再配合 -m 1
(匹配一次后退出)可以缩短复杂日志的搜索时间。
-i
:忽略大小写,处理大小写不一致的告警信息很方便。-E
:启用扩展正则,可直接写 grep -E "(WARN|ERROR)"
。--color=auto
:高亮命中关键字,在终端阅读更直观。将这些参数组合成 Shell 函数,后续排查直接调用。例如在 ~/.bashrc
中定义:
1 2 3 4 |
|
执行 gctx "timeout" service.log 2
,即可得到行号、关键字高亮、上下文行的结果。
-C/-A/-B
是获取上下文的核心选项,记住数字表示行数即可。-n
、--color
、-m
等参数可以提升排查效率。less -R
或 fzf
管道组合,能够在终端中进行二次筛选,让排查体验更顺滑。2025-06-23 08:33:00
最近在 Android 项目开发中遇到了几个构建错误,以下是解决方案,供遇到同样问题的开发者参考。
1 2 3 4 5 |
|
在 app/build.gradle
中添加以下配置:
1 2 3 4 5 6 7 |
|
此错误通常由多个依赖包含相同的 META-INF 文件引起,通过 excludes
排除重复文件即可解决。
1 2 3 |
|
在 app/build.gradle
中添加依赖替换规则:
1 2 3 4 5 |
|
Google 将 TensorFlow Lite 迁移到新包名 com.google.ai.edge.litert
,若项目同时包含新旧包名,会导致类冲突。通过依赖替换强制使用新包解决。
1 2 3 4 |
|
在项目根目录的 android/gradle.properties
文件中添加:
1
|
|
BouncyCastle 1.78 版本使用 Java 21 编译(class file major version 65),而 Jetifier 不支持此版本字节码。将相关 jar 包加入 Jetifier 忽略列表可避免转换错误。
以上三个问题是 Android 构建中常见的依赖冲突问题,解决思路包括:
遇到类似问题时,仔细分析错误信息,通常能找到相应解决方案。
2025-06-15 08:49:00
在 CI/CD 环境下,团队常遇到以下错误:
1
|
|
这通常是多个进程或脚本并发操作同一个 Git 仓库,导致元数据损坏或锁冲突。Git 并非为高并发本地操作设计,因此需要解决并发问题。
在自动化脚本中,例如:
1 2 |
|
如果多个任务同时执行,可能导致锁冲突或元数据损坏。
通过加锁机制,让所有 Git 操作串行执行。flock
是一个简单高效的工具,专为这种场景设计。
大多数 Linux 发行版自带 flock
(属于 util-linux
套件)。如果没有,可按以下方式安装:
1 2 |
|
1
|
|
1
|
|
安装后即可使用 flock
命令。
macOS 默认不包含 flock
,但可通过 Homebrew 安装兼容版本:
1
|
|
安装的是 Ben Noordhuis 的 flock
,语法与 Linux 版本基本一致。
提示:在 CI 服务(如 GitHub Actions)中,可在步骤中提前安装 flock
。
flock
用于在 shell 脚本中对文件加锁:
1
|
|
建议将锁文件放在 .git
目录下,避免污染业务代码目录。
假设有一个 deploy.sh
脚本:
1 2 3 4 |
|
加锁后修改为:
1 2 3 4 5 6 7 8 |
|
或者直接锁定整个脚本:
1
|
|
-n
:表示拿不到锁时立即退出(可选)。.git
目录下。flock
使 Git 操作串行,防止元数据损坏。flock
。flock
是必备工具,简单高效!如有问题,请在评论区讨论。
2024-11-03 00:49:00
前段时间,处理一个比较旧的 flutter plugin,涉及到 Android 的部分,一顿修改后,发现无法 gradle sync 成功。 报错如下,
1 2 3 4 5 6 7 8 9 10 |
|
根据分析上面的错误信息,判定与 gradle 有关,和修改的 kotlin 代码无关。
经过一些简短尝试,最终确定是 gradle 版本不匹配的问题(主要由这一句推断 because interface org.gradle.api.tasks.incremental.IncrementalTaskInputs is not a valid parameter to an action method.)。
classpath ‘com.android.tools.build:gradle:7.1.2’ // The Android Gradle plugin.
修改gradle/wrapper/gradle-wrapper.properties
distributionUrl=https://services.gradle.org/distributions/gradle-8.0-all.zip
修改成(或者对应的gradle 版本) distributionUrl=https://services.gradle.org/distributions/gradle-7.4-all.zip
查询,请访问 这里 https://developer.android.com/build/releases/gradle-plugin?#updating-gradle