MoreRSS

site icon技术小黑屋修改

89年出生的保定人在北京,Android 工程师, Infoq译者。
请复制 RSS 到你的阅读器,或快速订阅到 :

Inoreader Feedly Follow Feedbin Local Reader

技术小黑屋的 RSS 预览

Android 开发中的三个常见构建错误及解决方案

2025-06-23 08:33:00

最近在 Android 项目开发中遇到了几个构建错误,以下是解决方案,供遇到同样问题的开发者参考。

1. META-INF 文件冲突

错误信息

1
2
3
4
5
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:mergeDebugJavaResource'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.MergeJavaResWorkAction
   > 2 files found with path 'META-INF/versions/9/OSGI-INF/MANIFEST.MF' from inputs:

解决方案

app/build.gradle 中添加以下配置:

1
2
3
4
5
6
7
android {
    packagingOptions {
        resources {
            excludes += "META-INF/versions/9/OSGI-INF/MANIFEST.MF"
        }
    }
}

说明

此错误通常由多个依赖包含相同的 META-INF 文件引起,通过 excludes 排除重复文件即可解决。


2. TensorFlow Lite 库冲突

错误信息

1
2
3
Caused by: java.lang.RuntimeException: Duplicate class org.tensorflow.lite.DataType found in
modules jetified-litert-api-1.0.1-runtime (com.google.ai.edge.litert:litert-api:1.0.1) and
jetified-tensorflow-lite-api-2.12.0-runtime (org.tensorflow:tensorflow-lite-api:2.12.0)

解决方案

app/build.gradle 中添加依赖替换规则:

1
2
3
4
5
configurations.all {
    resolutionStrategy.dependencySubstitution {
        substitute module("org.tensorflow:tensorflow-lite") with module("com.google.ai.edge.litert:litert:1.0.1")
    }
}

说明

Google 将 TensorFlow Lite 迁移到新包名 com.google.ai.edge.litert,若项目同时包含新旧包名,会导致类冲突。通过依赖替换强制使用新包解决。


3. Jetifier 与 BouncyCastle 兼容性问题

错误信息

1
2
3
4
Caused by: java.lang.RuntimeException: Failed to transform
'/Users/xxxxx/.gradle/caches/modules-2/files-2.1/org.bouncycastle/bcprov-jdk18on/1.78/619aafb92dc0b4c6c
c4cf86c487ca48ee2d67a8e/bcprov-jdk18on-1.78.jar' using Jetifier.
Reason: IllegalArgumentException, message: Unsupported class file major version 65.

解决方案

在项目根目录的 android/gradle.properties 文件中添加:

1
android.jetifier.ignorelist=bcprov-jdk18on-1.78.jar,bcutil-jdk18on-1.78.jar

说明

BouncyCastle 1.78 版本使用 Java 21 编译(class file major version 65),而 Jetifier 不支持此版本字节码。将相关 jar 包加入 Jetifier 忽略列表可避免转换错误。


总结

以上三个问题是 Android 构建中常见的依赖冲突问题,解决思路包括: – 排除重复文件 – 替换冲突依赖 – 跳过不兼容的处理

遇到类似问题时,仔细分析错误信息,通常能找到相应解决方案。



使用 flock 解决 Git `unable to read tree` 问题

2025-06-15 08:49:00

背景

在 CI/CD 环境下,团队常遇到以下错误:

1
fatal: unable to read tree <SHA>

这通常是多个进程或脚本并发操作同一个 Git 仓库,导致元数据损坏或锁冲突。Git 并非为高并发本地操作设计,因此需要解决并发问题。

问题复现

在自动化脚本中,例如:

1
2
git fetch origin
git checkout some-branch

如果多个任务同时执行,可能导致锁冲突或元数据损坏。

解决思路

通过加锁机制,让所有 Git 操作串行执行。flock 是一个简单高效的工具,专为这种场景设计。

flock 安装

Linux

大多数 Linux 发行版自带 flock(属于 util-linux 套件)。如果没有,可按以下方式安装:

  • Debian/Ubuntu:
1
2
sudo apt-get update
sudo apt-get install util-linux
  • CentOS/RHEL:
1
sudo yum install util-linux
  • Arch:
1
sudo pacman -S util-linux

安装后即可使用 flock 命令。

macOS

macOS 默认不包含 flock,但可通过 Homebrew 安装兼容版本:

1
brew install flock

安装的是 Ben Noordhuis 的 flock,语法与 Linux 版本基本一致。

提示:在 CI 服务(如 GitHub Actions)中,可在步骤中提前安装 flock

flock 用法

flock 用于在 shell 脚本中对文件加锁:

1
flock <lockfile> <command>

建议将锁文件放在 .git 目录下,避免污染业务代码目录。

实战例子

假设有一个 deploy.sh 脚本:

1
2
3
4
#!/bin/bash
git fetch origin
git checkout some-branch
# ...more commands...

加锁后修改为:

1
2
3
4
5
6
7
8
#!/bin/bash
LOCK_FILE="/path/to/your/repo/.git/deploy.lock"

flock -n "$LOCK_FILE" bash <<'EOF'
git fetch origin
git checkout some-branch
# ...more commands...
EOF

或者直接锁定整个脚本:

1
flock -n /path/to/your/repo/.git/deploy.lock ./deploy.sh
  • -n:表示拿不到锁时立即退出(可选)。
  • 建议将锁文件放在 .git 目录下。

总结

  • 避免并发操作同一个 Git 仓库!
  • 使用 flock 使 Git 操作串行,防止元数据损坏。
  • Linux 下直接使用,macOS 通过 Homebrew 安装 flock
  • 锁粒度可适当放宽,确保安全优先。
  • 本地自动化操作 Git 时,flock 是必备工具,简单高效!

如有问题,请在评论区讨论。



Could not create task ':generateDebugRFile' 问题小记

2024-11-03 00:49:00

前段时间,处理一个比较旧的 flutter plugin,涉及到 Android 的部分,一顿修改后,发现无法 gradle sync 成功。 报错如下,

1
2
3
4
5
6
7
8
9
10
Could not create task ':generateDebugRFile'.
Cannot use @TaskAction annotation on method IncrementalTask.taskAction$gradle_core() because interface org.gradle.api.tasks.incremental.IncrementalTaskInputs is not a valid parameter to an action method.

* Try:
> Run with --debug option to get more log output.
> Run with --scan to get full insights.

* Exception is:
com.intellij.openapi.externalSystem.model.ExternalSystemException: Could not create task ':generateDebugRFile'.
Cannot use @TaskAction annotation on method IncrementalTask.taskAction$gradle_core() because interface org.gradle.api.tasks.incremental.IncrementalTaskInputs is not a valid parameter to an action method.

根据分析上面的错误信息,判定与 gradle 有关,和修改的 kotlin 代码无关。

经过一些简短尝试,最终确定是 gradle 版本不匹配的问题(主要由这一句推断 because interface org.gradle.api.tasks.incremental.IncrementalTaskInputs is not a valid parameter to an action method.)。

原因与解法

  • 原因为 Android Gradle Plugin 与 gradle 不匹配。
  • 可以修改 gradle plugin 版本,也可以修改 gradle 版本。

修改 AGP 版本

classpath ‘com.android.tools.build:gradle:7.1.2’ // The Android Gradle plugin.

修改 gradle 版本

修改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

如何确定 AGP 与 gradle 对应关系

查询,请访问 这里 https://developer.android.com/build/releases/gradle-plugin?#updating-gradle



Android 模拟器实现 hosts 修改

2023-03-12 20:50:00

有时候我们需要使用 Android 模拟器来 绑定一下 hosts 来实现功能的开发与验证,刚好最近遇到了这样的需求,处理完成,简单记录一下。

替换m1 实现(针对 苹果 M1 芯片才需要处理)

下载这个文件 https://github.com/google/android-emulator-m1-preview/releases/download/0.2/emulator-darwin-aarch64-0.2-engine-only.zip

解压,然后将 emulatoremulator-check 替换掉这里面的文件 ~/Library/Android/sdk/tools/ (原有的可以备份为 xxx_backup)

查看 avd_id

1
2
3
4
5
6
7
~/Library/Android/sdk/tools/emulator -list-avds
Pixel6ProAPI33
Pixel_3a_API_33_arm64-v8a
Pixel_6_API_22
Pixel_6_API_28
Pixel_6_Pro_API_23
Pixel_6_Pro_API_30_X86

启动 avd,可写入状态

1
~/Library/Android/sdk/tools/emulator -avd Pixel_3a_API_33_arm64-v8a  -writable-system

新起终端tab 执行

  1. adb root
  2. adb remount
  3. adb push your_hosts_on_mac /etc/hosts

验证ping

假设上面的 hosts 我们新增了 127.0.0.1 baidu.com

1
2
3
4
5
6
adb shell

ping baidu.com
PING baidu.com (127.0.0.1) 56(84) bytes of data.
64 bytes from baidu.com (127.0.0.1): icmp_seq=1 ttl=64 time=1.55 ms
64 bytes from baidu.com (127.0.0.1): icmp_seq=2 ttl=64 time=0.180 ms

注意: hosts 修改建议在 mac 上进行处理,然后使用adb push your_hosts_on_mac /etc/hosts 替换手机内的hosts。手机内置的 vi 很弱,可能无法编辑。

以上。



Vs Code 快速实现 重写 方法

2023-02-12 20:20:00

作为一个从 Android Studio/IntelliJ 切到 VS code 的开发者,一开始会遇到各种不适应的情况。 比如快捷键不一样,使用习惯不一样等。

这里将简单记录一下 个人遇到的一些痛点,比如如何重写方法。

在 Android Studio/ IntelliJ 中,使用起来很简单,比如弹出这个菜单,选择 Override Methods 即可,实现重写 initState 方法

https://asset.droidyue.com/image/2023/h1/as_intellij_override_methods.png

但是切到 Vs Code 后,发现找不到快捷键,后来经过一些摸索,还是找到了 如何快速实现方法重写的方法。

如下图,只需要输入待重写的方法的首字母,即可弹出提示。

https://asset.droidyue.com/image/2023/h1/vscode_override_method.png

VS Code 的方式显得会更加的简单。(后来才发现同样的方式 在 Android Studio/Intellij 也支持,Orz)



Merge(Pull) Request 推荐的标签列表

2022-11-27 21:35:00

一个Merge Request 的 阶段

  1. 代码添加或修改,需要进行review
  2. 代码review结束,需要修改
  3. 重复步骤1和步骤2,直到达到可以合并的标准

角色

  • MR submitter 负责提交Merge Request,并针对review做修改
  • MR reviewer 负责review Merge Request,提出MR中存在的问题,该角色可以对应多个人
  • MR dispatcher 负责分发MR,修改或增加MR reviewer
  • MR terminator 最终负责MR结果走向的人,比如合并或者关闭

注意

  • 上述角色至少需要两个人
  • 因权限问题, MR reviewer 可能无权限合并该MR

有哪些标签

MR:Needs Review(MR:需要Review)

  • 当MR创建或者进行了更新,需要人员Review时,MR submitter 设置该标签
  • 如果MR对应的内容不需要跟版,不需要现在合并的,不要增加该Lable
  • 如果一个MR,当前的label不包含MR:Needs Review,MR reviewer 则不会review

MR:Reviewed With Comments(MR:需要修改)

  • MR reviewer 进行了review,并提出了一些评论来记录发现的问题和疑问
  • MR reviewer 移除 MR:Needs Review 并添加标签 MR:Reviewed With Comments
  • MR submitter 根据提出的问题和疑问进行修改或回答,当修改完毕后,移除标签 MR:Reviewed With Comments,并设置MR:Needs Review

Good to Merge(可以合并)

  • 经过上面的来回操作,在某一点,MR达到了一个可以合并的时候,这时候需要移除前面的标签,设置成Good to Merge
  • 设置这个标签,需要由MR reviewer 操作,而不是MR submitter
  • 设置完这个标签后,MR不需要再更新
  • 因MR reviewer不一定有merge权限,这一标签还是有必要的

Do Not Merge(请勿合并)

  • 禁止合并标签,该MR可以被 review,但是不要合并进来.
  • 适用于未来的需求,目前尚不需要加入到主分支
  • 辅助标签,更加明确表明不需要合并当前MR

待验收

  • 该功能没有开始进行验收(测试,UI,UE,产品,数据等)
  • 如果当前MR包含待验收,通常不会被合并

验收中

  • 该功能正在处于验收中(测试,UI,UE,产品,数据等)
  • 如果当前MR包含该标签,通常不会被合并

验收通过

  • 该功能已经通过验收(测试,UI,UE,产品,数据等)
  • 如果当前MR包含验收通过,可以进行合并

BugFix

  • 仅用于修复线上版本的崩溃提交时,使用

可能不上线

  • 有些MR已经完成,但不确定什么版本引入,需要增加该标签

技术需求