我遇到了一个我无法解决的问题。
首先,我在Ubuntu 14.04上为Android编译了openFrameworks androidVideoExample(我在命令行使用了gradlew assembleDebug
);然后,使用adb install ./build/outputs/apk/androidVideoExample-debug.apk
在Android设备上部署生成的.apk。我已经部署在Android 4.2.2设备和Android 6.0.1设备上 - 它可以在两者上运行而不会崩溃。
然后,我尝试在我的测试应用程序(myApp
)的代码中使用该示例中使用的视频组件openFrameworks ofVideoPlayer,该代码之前已在这些设备上构建并运行良好。当我构建它时 - 再次使用gradlew assembleDebug
- 它构建正常,并且在两个设备上使用adb install ./build/outputs/apk/myApp-debug.apk
安装也很好。但是,当我运行它时,它会在两台设备上启动时崩溃。
所以,我用adb logcat
进行了检查 - 4.2.2设备没有给我一个有用的跟踪;然而,6.0.1最终有类似的东西:
--------- beginning of crash
01-29 23:56:22.551 8938 8973 F libc : Fatal signal 6 (SIGABRT), code -6 in tid 8973 (Thread-21892)
01-29 23:56:22.653 383 383 D clmlib : Got activities:0x0000000E
01-29 23:56:22.654 383 383 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
01-29 23:56:22.654 383 383 F DEBUG : UUID: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
01-29 23:56:22.655 383 383 F DEBUG : Build fingerprint: 'XXXXXXXXXXXXXXX:user/release-keys'
01-29 23:56:22.655 383 383 F DEBUG : Revision: '0'
01-29 23:56:22.655 383 383 F DEBUG : ABI: 'arm'
01-29 23:56:22.655 383 383 F DEBUG : pid: 8938, tid: 8973, name: Thread-21892 >>> cc.openframeworks.myApp <<<
01-29 23:56:22.655 383 383 F DEBUG : signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
01-29 23:56:22.694 383 383 F DEBUG : Abort message: 'art/runtime/java_vm_ext.cc:410] JNI DETECTED ERROR IN APPLICATION: JNI NewGlobalRef called with pending exception java.lang.ClassNotFoundException: Didn't find class "cc.openframeworks.OFAndroidVideoPlayer" on path: DexPathList[[directory "."],nativeLibraryDirectories=[/vendor/lib, /system/lib]]'
01-29 23:56:22.694 383 383 F DEBUG : r0 00000000 r1 0000230d r2 00000006 r3 967e6978
01-29 23:56:22.694 383 383 F DEBUG : r4 967e6980 r5 967e6930 r6 0000000b r7 0000010c
...
首先,请注意这些关于这些视频对象关系的grep片段:
openFrameworks/libs/openFrameworks/video/ofVideoPlayer.h: #include "ofxAndroidVideoPlayer.h"
openFrameworks/addons/ofxAndroid/src/ofxAndroidVideoPlayer.cpp: jclass localClass = env->FindClass("cc/openframeworks/OFAndroidVideoPlayer");
openFrameworks/addons/ofxAndroid/ofAndroidLib/src/cc/openframeworks/OFAndroidVideoPlayer.java:public class OFAndroidVideoPlayer extends OFAndroidObject implements OnFrameAvailableListener {
好的,所以我认为消息'没有找到课程“cc.openframeworks.OFAndroidVideoPlayer”'意味着我从我的.apk中错过了某些课程;但是,我试过这个:
$ zipgrep OFAndroidVideoPlayer /path/to/build/outputs/apk/myApp-debug.apk
classes.dex:Binary file (standard input) matches
lib/armeabi-v7a/libOFAndroidApp.so:Binary file (standard input) matches
好吧,看起来他们在那里?尝试看得更近,也使用dexdump
:
$ cd /tmp
$ mkdir unpack
$ cd unpack
$ unzip /path/to/build/outputs/apk/myApp-debug.apk
$ /path/to/sdk/build-tools/19.1.0/dexdump ./classes.dex | grep OFAndroidVideoPlayer
Class descriptor : 'Lcc/openframeworks/OFAndroidVideoPlayer$1;'
#0 : (in Lcc/openframeworks/OFAndroidVideoPlayer$1;)
type : 'Lcc/openframeworks/OFAndroidVideoPlayer;'
#0 : (in Lcc/openframeworks/OFAndroidVideoPlayer$1;)
type : '(Lcc/openframeworks/OFAndroidVideoPlayer;)V'
0x0000 - 0x0006 reg=0 this Lcc/openframeworks/OFAndroidVideoPlayer$1;
#0 : (in Lcc/openframeworks/OFAndroidVideoPlayer$1;)
0x0000 - 0x0025 reg=2 this Lcc/openframeworks/OFAndroidVideoPlayer$1;
source_file_idx : 358 (OFAndroidVideoPlayer.java)
Class descriptor : 'Lcc/openframeworks/OFAndroidVideoPlayer$2;'
#0 : (in Lcc/openframeworks/OFAndroidVideoPlayer$2;)
type : 'Lcc/openframeworks/OFAndroidVideoPlayer;'
#0 : (in Lcc/openframeworks/OFAndroidVideoPlayer$2;)
type : '(Lcc/openframeworks/OFAndroidVideoPlayer;)V'
0x0000 - 0x0006 reg=0 this Lcc/openframeworks/OFAndroidVideoPlayer$2;
#0 : (in Lcc/openframeworks/OFAndroidVideoPlayer$2;)
0x0000 - 0x0001 reg=0 this Lcc/openframeworks/OFAndroidVideoPlayer$2;
source_file_idx : 358 (OFAndroidVideoPlayer.java)
Class descriptor : 'Lcc/openframeworks/OFAndroidVideoPlayer$3;'
#0 : (in Lcc/openframeworks/OFAndroidVideoPlayer$3;)
type : 'Lcc/openframeworks/OFAndroidVideoPlayer;'
#0 : (in Lcc/openframeworks/OFAndroidVideoPlayer$3;)
type : '(Lcc/openframeworks/OFAndroidVideoPlayer;)V'
0x0000 - 0x0006 reg=0 this Lcc/openframeworks/OFAndroidVideoPlayer$3;
#0 : (in Lcc/openframeworks/OFAndroidVideoPlayer$3;)
0x0000 - 0x0007 reg=2 this Lcc/openframeworks/OFAndroidVideoPlayer$3;
source_file_idx : 358 (OFAndroidVideoPlayer.java)
...
#28 : (in Lcc/openframeworks/OFAndroidVideoPlayer;)
0x0000 - 0x001d reg=2 this Lcc/openframeworks/OFAndroidVideoPlayer;
source_file_idx : 358 (OFAndroidVideoPlayer.java)
嗯 - 至少这表示cc/openframeworks/OFAndroidVideoPlayer
位于我classes.dex
的{{1}}中 - 所以这应该意味着班级在那里?事实上,.apk
和dexdump ./classes.dex ... | grep OFAndroidVideoPlayer
的{{1}}输出相同!
我还尝试了dex-method-counts,并且对于myApp-debug.apk
“总方法计数:710”,因此远远低于需要multidex的65536限制。
否则,这些类由openFrameworks在这里编译:
androidVideoExample-debug.apk
所以,4个用于调试的java类和4个用于发布的java类 - 我猜测这些类最终会出现在myApp-debug.apk
中。
最后,我开始以二进制模式在这些项目的源文件夹中进行grepping,希望找到差异:
$ find /path/to/openFrameworks/ -name '*AndroidVideoPla*'
...
/path/to/openFrameworks/addons/ofxAndroid/ofAndroidLib/build/intermediates/classes/debug/cc/openframeworks/OFAndroidVideoPlayer$3.class
/path/to/openFrameworks/addons/ofxAndroid/ofAndroidLib/build/intermediates/classes/debug/cc/openframeworks/OFAndroidVideoPlayer.class
/path/to/openFrameworks/addons/ofxAndroid/ofAndroidLib/build/intermediates/classes/debug/cc/openframeworks/OFAndroidVideoPlayer$2.class
/path/to/openFrameworks/addons/ofxAndroid/ofAndroidLib/build/intermediates/classes/debug/cc/openframeworks/OFAndroidVideoPlayer$1.class
/path/to/openFrameworks/addons/ofxAndroid/ofAndroidLib/build/intermediates/classes/release/cc/openframeworks/OFAndroidVideoPlayer$3.class
/path/to/openFrameworks/addons/ofxAndroid/ofAndroidLib/build/intermediates/classes/release/cc/openframeworks/OFAndroidVideoPlayer.class
/path/to/openFrameworks/addons/ofxAndroid/ofAndroidLib/build/intermediates/classes/release/cc/openframeworks/OFAndroidVideoPlayer$2.class
/path/to/openFrameworks/addons/ofxAndroid/ofAndroidLib/build/intermediates/classes/release/cc/openframeworks/OFAndroidVideoPlayer$1.class
...我将这些输出与classes.dex
进行了比较。我唯一能找到的是,grep -rao .......OFAndroidVideoPlayer...... . | tr -cd '\11\12\40-\176' > /tmp/a2
源文件夹将这些作为重复条目:
meld
现在这些都是myApp
./.gradle/2.4/taskArtifacts/fileSnapshots.bin: /to/openFrameworks/addons/ofxAndroid/ofAndroidLib/build/intermediates/classes/release/cc/openframeworks/OFAndroidVideoPlayer.class
./.gradle/2.4/taskArtifacts/fileSnapshots.bin: /to/openFrameworks/addons/ofxAndroid/ofAndroidLib/build/intermediates/classes/release/cc/openframeworks/OFAndroidVideoPlayer$1.cla
./.gradle/2.4/taskArtifacts/fileSnapshots.bin: /to/openFrameworks/addons/ofxAndroid/ofAndroidLib/build/intermediates/classes/release/cc/openframeworks/OFAndroidVideoPlayer$3.cla
./.gradle/2.4/taskArtifacts/fileSnapshots.bin: /to/openFrameworks/addons/ofxAndroid/ofAndroidLib/build/intermediates/classes/release/cc/openframeworks/OFAndroidVideoPlayer$2.cla
./.gradle/2.4/taskArtifacts/fileSnapshots.bin: /to/openFrameworks/addons/ofxAndroid/ofAndroidLib/build/intermediates/classes/debug/cc/openframeworks/OFAndroidVideoPlayer.class
./.gradle/2.4/taskArtifacts/fileSnapshots.bin: /to/openFrameworks/addons/ofxAndroid/ofAndroidLib/build/intermediates/classes/debug/cc/openframeworks/OFAndroidVideoPlayer$2.cla
./.gradle/2.4/taskArtifacts/fileSnapshots.bin: /to/openFrameworks/addons/ofxAndroid/ofAndroidLib/build/intermediates/classes/debug/cc/openframeworks/OFAndroidVideoPlayer$3.cla
./.gradle/2.4/taskArtifacts/fileSnapshots.bin: /to/openFrameworks/addons/ofxAndroid/ofAndroidLib/build/intermediates/classes/debug/cc/openframeworks/OFAndroidVideoPlayer$1.cla
中的重复项 - 而不是gradlew
本身 - 所以我不会遇到重复的类错误(比如说,{ {3}})。此外,除了两个项目中fileSnapshots.bin
中.apk
的现有条目外,这些还是重复的。然后我只是删除了OFAndroidVideoPlayer
目录的内容:
fileSnapshots.bin
...然后我.gradle/2.4/taskArtifacts/
再次重建rm -rfv .gradle/2.4/taskArtifacts/*
- 这次,gradlew assembleDebug
中没有重复项(myApp
{{1} } fileSnapshots.bin
与myApp
的引用数相同。但是,应用程序在启动时仍会崩溃,但错误完全相同。
所以,据我所知,fileSnapshots.bin
OFAndroidVideoPlayer
androidVideoExample
中OFAndroidVideoPlayer
的{{1}}类,但是JNI仍然无法在运行时看到它们,在应用程序启动时?可能是什么原因 - 我怎么能进一步调试呢?
例如,我还有哪些方法可以比较工作.dex
和崩溃.apk
之间在“缺少”myApp
Java类方面的差异?
答案 0 :(得分:0)
请注意搜索路径中没有dex文件:
...on path: DexPathList[[directory "."],nativeLibraryDirectories=[/vendor/lib, /system/lib]]'
通常,当有人附加一些以本机启动的线程然后尝试加载Java类时,会发生这种情况。这些线程的默认类加载器并不知道你的dex。您可以尝试从最初在java中创建的任何线程执行该查找。从JNI_OnLoad()
执行此操作将非常理想。