乐于分享
好东西不私藏

第7篇:不让看源码?我硬看——反编译JAR当侦探

第7篇:不让看源码?我硬看——反编译JAR当侦探
系列简介:我不会写代码,雇了三个AI做"AI语音通话复盘App"。上一集确定了核心方案:App在通话时抓取原始音频(音频帧),推到服务器转文字。这一集,写代码的AI开始动手,结果连错三次,被逼出整个系列最"侦探"的一集——反编译SDK。

三秒钟背景

  1. 我们要做"打完电话自动生成AI复盘报告"的App。
  2. 报告的第一步是拿到通话声音,方案是用腾讯TRTC的音频帧回调——通话时每20毫秒,引擎把一小块声音递给我们。
  3. 我们要写一个"接声音的代码"(AudioStreamPublisher.kt)。这一集就是写这段代码的九九八十一难。

好,开始。

TASK-019:第一步先验证——回调到底有没有?

顾问AI有个好习惯:先验证,再写代码。它安排终端AI先做一件事:TRTC的音频帧回调,是不是真的能触发

终端AI装上测试版本,跑了一通电话,检查日志——发现问题了:

回调函数里啥也没有(空壳)。音频数据从来没有真正进入过我们的缓冲。

翻译成大白话:水管接上了,水龙头也拧开了,但水从来没有流进我们的水桶——因为水管中间是断的(代码里压根没把TRTC的音频数据接进来)。

结论:回调机制存在,但需要"接线"——把TRTC的音频数据真正接到我们的代码里。这个接线工作,派给编程AI。

TASK-020:编程AI猜API——全猜错了

编程AI开工,写代码接音频。写完,终端AI拿去编译——编译失败

失败原因是:编程AI用了一堆不存在的API名字

这里必须解释一下什么是"API"——API就是别人家的服务给你提供的"标准动作",比如:

你跟银行说"我要取钱",银行按流程给你办。这里的"取钱"就是一个API。 但你要是跟银行说"我要用瞬间移动取钱",银行就只能回你一脸问号。

编程AI写的代码里,用了 TRTCAudioFrameListenerTRTCAudioFrame 这些名字,但TRTC的SDK里根本没有这些名字——就像"瞬间移动"一样,不存在。

为什么会猜错?因为编程AI不知道TRTC的真实API长什么样,它只能凭经验猜。AI写代码有个致命毛病:不知道就猜,猜错了编译就崩

终端AI一看编程AI这水平(连错两回),简直太坑了,干脆自己先写了个"手动接口+TODO注释"的过渡版本——先保证不崩,等找到真相再填。

TASK-021:反编译JAR——把装订好的书拆了看

怎么找真相?SDK是一个打包好的 .jar 文件——就像一本装订好的书,只能看目录,看不到正文。

终端AI祭出绝招:反编译

反编译 = 把装订好的书拆开,一页页摊平,把编译过的代码还原成接近原文的样子。

工具是JDK自带的 javap。终端AI把TRTC的SDK(叫LiteAVSDK)整个反编译,一行一行翻,终于找到了真实API,并且发现了两个关键真相:

真相一:类名藏得深。

  • 编程AI猜的:TRTCAudioFrameListener ❌
  • 真实的:TRTCCloudListener.TRTCAudioFrameListener ✅(藏在另一个大类里面)

真相二:参数顺序是反的(最坑的发现)。

  • 编程AI猜的:onRemoteUserAudioFrame(userId, frame) —— 先"谁说的",再"说了啥"
  • 真实的:onRemoteUserAudioFrame(frame, userId) —— 先"说了啥",再"谁说的"

这个参数顺序问题有多坑?想象一下:

你给快递公司打电话报地址:"我家住在……"快递员记下了。但你的电话其实是打给了银行,银行听你说"我家住在……"也给你记下了。两边都在"记",但记的字段顺序不一样——你把地址说在前面,银行却以为那是姓名。

代码里参数顺序写反,轻则编译失败,重则数据全错(把"谁说的"当成"说了啥",转写出来全是乱码)。

TASK-022:按真相修正——终于通了

真相在手,修正就快了。编程AI按反编译找到的真实API改代码:

  1. import 改对
    引入真实的类 TRTCCloudDef 和 TRTCCloudListener
  2. 参数顺序改对
    onRemoteUserAudioFrame(frame, userId) —— frame在前,userId在后
  3. 6个回调全实现
    TRTC要求你把所有音频相关的回调都实现一遍(本地声音、远端声音、混音、耳返……就算用不上也得写上,不然编译不过)
  4. 注销也对
    挂断电话时用 setAudioFrameListener(null) 把监听器摘掉——不然通话结束了还在偷偷抓声音,耗电又泄露隐私

改完,编译通过!再用真机验证:音频帧真的进来了,声音数据开始源源不断流进我们的缓冲。

至此,TASK-019~022 闭环:从"回调是空壳"到"声音真正进了我们的管道"。

这件事为什么值得单写一篇?

因为这是AI协作开发里最典型的坑,没有之一:

AI不知道真实API,它会猜;猜错了,编译崩;编译不崩的,运行也会出诡异bug。

而我们这次靠反编译解决了它。项目里后来立了一条规矩:所有SDK的API,必须先用反编译或官方文档验证过,写进一张"API速查表",编程AI写代码前先查表,禁止猜

这篇的收获

大白话
教训
回调是空壳
水管接上了但没通水
先验证再写代码
API猜错编译失败
跟银行说"瞬间移动"
AI写代码会猜API,猜错就崩
参数顺序反了
地址和姓名记反了
反编译SDK,找到真相
立规矩
写进速查表,禁止猜
踩过的坑要变成制度

一句大实话

程序员圈有句话叫"源码面前,了无秘密"——翻译一下:只要你有办法看到源码(哪怕是反编译),就没有查不清的真相。这一集的技术含量对零基础的你可能有点高,但记住结论就行:遇到"猜不准"的事情,别猜,去把真相挖出来。

下集预告

声音终于进管道了!但声音是要送到服务器去的。服务器长什么样?谁来收声音?谁来存文件?

下一集,我们正式搭建服务器的"三兄弟":一个负责收声音(WebSocket接收器)、一个负责调度分析(编排器)、一个负责对外提供接口(API服务)。然后,第一次端到端测试——手机上打一通电话,声音经过服务器,最后能不能变成文字?

我是Taobig,一个一行代码都不会写、全靠AI做产品的独立开发者

这里记录的是我真实的开发过程——能成、能翻车、能学到东西。关注我,一起看代码怎么变成产品。

喜欢这篇的话,点个「在看」,让我知道你在看。