You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Xcode项目中集成apktool可执行文件与jar包并实现调用

问题1:文件存放方案与路径获取方法
  • 不要把apktool可执行文件和apktool.jar放在Assets.xcassets目录下,该目录下的所有资源都会被Xcode编译为统一的Assets.car归档文件,无法直接获取单个文件的POSIX路径供shell调用。
  • 正确做法是将两个文件直接拖入项目,在弹出的添加选项中勾选对应Target的Target Membership,同时确保文件被添加到目标的Build Phases > Copy Bundle Resources列表中,Xcode会在构建时自动将这两个文件拷贝到App包的Contents/Resources目录下。
  • 路径获取的正确代码:
// 直接通过Bundle获取资源路径,不需要手动拼接
guard let apktoolPath = Bundle.main.path(forResource: "apktool", ofType: nil),
      FileManager.default.fileExists(atPath: apktoolPath) else {
    // 异常处理:可执行文件不存在
    return -1
}
  • 额外注意:需要保证apktool可执行文件有执行权限,你可以在构建阶段添加Run Script脚本来自动修复权限,避免打包后权限丢失:
chmod +x "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/Contents/Resources/apktool"
问题2:正确调用apktool的实现方案
  • 原生的Process调用需要注意环境变量问题,apktool本质是shell脚本,依赖系统Java运行环境,建议通过/usr/bin/env启动来自动加载系统环境变量,避免找不到Java的问题。
  • 修正后的完整执行代码示例:
@discardableResult
func runApktool(_ args: String...) -> Int32 {
    let task = Process()
    // 通过env加载系统环境变量
    task.launchPath = "/usr/bin/env"
    
    // 获取apktool可执行文件路径
    guard let apktoolPath = Bundle.main.path(forResource: "apktool", ofType: nil) else {
        print("错误:apktool可执行文件不存在")
        return -1
    }
    
    // 拼接参数:第一个参数是apktool路径,后面是业务参数
    var allArguments = [apktoolPath]
    allArguments.append(contentsOf: args)
    task.arguments = allArguments
    
    // 可选:添加管道捕获输出日志,方便排查问题
    let outputPipe = Pipe()
    task.standardOutput = outputPipe
    task.standardError = outputPipe
    
    task.launch()
    task.waitUntilExit()
    
    // 可选:打印执行日志
    let logData = outputPipe.fileHandleForReading.readDataToEndOfFile()
    if let log = String(data: logData, encoding: .utf8), !log.isEmpty {
        print("apktool执行日志:\(log)")
    }
    
    return task.terminationStatus
}
  • 调用示例:如果要解码APK,直接传对应参数即可:
let status = runApktool("d", "/path/to/your/test.apk", "-o", "/path/to/output/folder")
if status == 0 {
    print("执行成功")
} else {
    print("执行失败,错误码:\(status)")
}
  • 额外注意:如果你的App开启了沙盒模式,需要在Signing & Capabilities中勾选Allow Unsigned Executable Memory、Disable Library Validation两个权限,否则子进程调用会被沙盒拦截;如果不需要上架App Store,直接关闭沙盒可避免各类权限问题。

内容的提问来源于stack exchange,提问作者Saad Mahboob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 12:54:03