mcpField
1
1k-patching-native-modules

1k-patching-native-modules

github.com/onekeyhq开发2.5k59 次安装今天更新
代码仓库

关于 1k-patching-native-modules

指导开发者分析崩溃日志、修复原生模块问题并生成补丁的技能。流程覆盖 iOS 与 Android 定位、清理构建产物及使用 patch-package 验证补丁。

主要功能

  1. 01解析 iOS 与 Android 崩溃日志
  2. 02定位原生模块源码与常见故障
  3. 03应用空值和内存安全检查
  4. 04清理构建产物后生成补丁
  5. 05检查补丁内容并准备提交

适用场景

  1. 01排查原生模块导致的应用崩溃
  2. 02修复 Swift 或 Kotlin 中的空值问题
  3. 03避免 Android 构建文件进入补丁
  4. 04为依赖模块变更生成并核验补丁

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/onekeyhq/app-monorepo --skill 1k-patching-native-modules

安装后在 Claude Code 中输入/1k-patching-native-modules确认已加载。

详细介绍

修补原生模块

按照以下工作流分析崩溃日志、修复原生模块缺陷并生成补丁。

工作流概览

1. Analyze Crash Log → 2. Locate Bug → 3. Fix Code → 4. Clean Build Artifacts → 5. Generate Patch → 6. Commit & PR

步骤 1:分析崩溃日志

iOS 崩溃(EXC_BAD_ACCESS / KERN_INVALID_ADDRESS)

需要提取的关键信息:

  • 异常类型:EXC_BAD_ACCESS、SIGABRT 等
  • 堆栈跟踪:确定发生崩溃的函数
  • 内存地址:有助于识别空指针问题
  • 库:发生崩溃的原生模块

崩溃模式示例:

EXC_BAD_ACCESS: KERN_INVALID_ADDRESS at 0x3c61c1a3b0d0
 objc_msgSend in unknown file
 -[SDWebImageManager cacheKeyForURL:context:]  ← Crashing function
 -[SDWebImageManager loadImageWithURL:options:context:progress:completed:]
Android 崩溃(NullPointerException / OOM)

请查找:

  • 异常类:NullPointerException、OutOfMemoryError
  • 堆栈跟踪:Java/Kotlin 方法调用链
  • 线程信息:主线程还是后台线程

步骤 2:定位缺陷

查找原生模块源码
# iOS (Swift/Objective-C)
ls node_modules/<package>/ios/

# Android (Kotlin/Java)
ls node_modules/<package>/android/src/main/java/
常见崩溃原因
崩溃类型常见原因修复模式
EXC_BAD_ACCESS解引用空指针添加 guard let 检查
KERN_INVALID_ADDRESS访问已释放的内存使用弱引用
NullPointerException访问空对象添加空值检查
OutOfMemoryError处理大型图像/数据添加大小限制

步骤 3:修复代码

iOS(Swift)- 空值检查模式
// Before (crashes when uri is nil)
imageManager.loadImage(with: source.uri, ...)

// After (safe)
guard let sourceUri = source.uri, !sourceUri.absoluteString.isEmpty else {
  onError(["error": "Image source URI is nil or empty"])
  return
}
imageManager.loadImage(with: sourceUri, ...)
Android(Kotlin)- 空值检查模式
// Before
val uri = source.uri
loadImage(uri)

// After
val uri = source.uri ?: return
if (uri.toString().isEmpty()) return
loadImage(uri)

步骤 4:清理构建产物(重要)

生成补丁前,必须清理 Android 构建缓存:

# Remove Android build artifacts to avoid polluting the patch
rm -rf node_modules/<package>/android/build

# For expo-image specifically:
rm -rf node_modules/expo-image/android/build

这很重要,原因如下:

  • Android 构建会生成 .class、.jar 和二进制文件
  • 这些文件会污染补丁文件(可能增至 5000 多行)
  • patch-package 会包含这些不需要的文件

步骤 5:生成补丁

# Generate patch file
npx patch-package <package-name>

# Example:
npx patch-package expo-image

补丁文件位置:patches/<package-name>+<version>.patch

验证补丁内容
# Check patch doesn't include unwanted files
grep -c "android/build" patches/<package-name>*.patch
# Should return 0

# View actual changes
head -100 patches/<package-name>*.patch

步骤 6:提交并创建 PR

# Stage patch file
git add patches/<package-name>*.patch

# Commit with descriptive message
git commit -m "fix(ios): prevent EXC_BAD_ACCESS crash in <package> when <condition>

Add guard checks in <package> native layer to prevent crash when <scenario>.

Fixes Sentry issue #XXXXX"

# Create PR
gh pr create --title "fix(ios): <description>" --base x

常见软件包及其原生代码位置

软件包iOS 源码Android 源码
expo-imagenode_modules/expo-image/ios/node_modules/expo-image/android/src/
react-nativenode_modules/react-native/React/node_modules/react-native/ReactAndroid/
@react-native-async-storage/async-storagenode_modules/@react-native-async-storage/async-storage/ios/...android/src/
react-native-reanimatednode_modules/react-native-reanimated/ios/...android/src/

现有补丁参考

查看现有补丁,了解相关模式:

ls patches/
cat patches/expo-image+3.0.10.patch

故障排查

补丁文件过大
# Clean all build artifacts
rm -rf node_modules/<package>/android/build
rm -rf node_modules/<package>/ios/build
rm -rf node_modules/<package>/.gradle

# Regenerate
npx patch-package <package>
补丁无法应用
# Check package version matches
cat node_modules/<package>/package.json | grep version

# Rename patch if version changed
mv patches/<package>+old.patch patches/<package>+new.patch
Swift/Kotlin 语法帮助

Swift guard let:

guard let value = optionalValue else {
  return  // Must exit scope
}
// value is now non-optional

Kotlin 空值检查:

val value = nullableValue ?: return
// value is now non-null

相关文件

  • 补丁目录:patches/
  • expo-image iOS:node_modules/expo-image/ios/ImageView.swift
  • expo-image Android:node_modules/expo-image/android/src/main/java/expo/modules/image/

评论

支持 Markdown