记一次jin开发遇到的很欲哭无泪的报错

JNI DETECTED ERROR IN APPLICATION: use of invalid jobject 0x1388

遇到这个错让人很头疼,字面上的意思就是说你传进来的对象是无效的,这个就很难理解了,要么是null,要么就是好的,无效怎么解释?先不管了,用debug模式来运行应用,会大概定位到出错的地方

图一:
记一次jin开发遇到的很欲哭无泪的报错
对照着上图来跟这个问题
途中标1的地方告诉我们再调jni里面的GetIntField的方法是出了错(但是,这只是表面现象,是不准确的,但是能打给定位大出错的位置,我们先记住obj的这个0x00001388值,接下来我们看标2的地方,这是方法调用的进栈顺序,对于我们有用的就两行,我们点击下面那一行会定位到出错的位置,如下图:

图二:
记一次jin开发遇到的很欲哭无泪的报错
标1的地方就是jni提示我们崩的地方,但是,我经过上上下下,反反复复的检查也没检查出来这个方法我传的这个jVideoStreamFormat参数有什么问题,为什么我要找jVideoStreamFormat这个参数而不是其他地方呢,以往的经验告诉我,jni的报错在debug模式下定位的并不十分准确,我只能在他定位的地方周围的变量都翻一遍,图一中我们看到报错的obj的hash值是0x00001388,我们看到标2的地方,hash的只是一样的,那我就确定了,是jVideoStreamFormat这个值有问题,但是问题在哪呢,这时我注意到了标3和4的地方,jAudioStreamFormat这个值为null,startTime和endTime的值为0,这就不可能了,这俩值是我在同一个地方new的:

图三:
记一次jin开发遇到的很欲哭无泪的报错
确实没得问题,这下不是一个问题了,这些参数的值怎么都乱了,顿时想面壁!
我在短暂的冷静之后又重新从头到尾的捋了一遍,从定义函数的地方
图四:
记一次jin开发遇到的很欲哭无泪的报错
再到jni里注册函数:
图五(由于方法签名太长,所以截成了两张:
记一次jin开发遇到的很欲哭无泪的报错
记一次jin开发遇到的很欲哭无泪的报错
这里我把三处地方都做了对比,终于有了新发现,我在java里定义的native方法的参数类型,startTime 和 endTime是long类型的(图四),但是在jni那层里实现的却是jint类型(图二),于是我把jni层的代码函数参数改成jlong类型的再次运行,
记一次jin开发遇到的很欲哭无泪的报错
没有出错,oh,Mygod!真是一次惨痛的教训,我们平时在java里long类型装int类型,编辑器都会提示我们强转类型,或者改变类型,但是在传往jni的路上可没人会提醒你,自能自己小心了