Rob*_*ree 2 java-native-interface android-ndk android-5.0-lollipop
--EDIT--由于模糊的build.gradle,我有太多版本的共享库浮动了...
./src/main/jniLibs/armeabi-v7a/libaudioboo-native.so
rob@ app$ rm ./src/main/libs/armeabi-v7a/libaudioboo-native.so
rob@ app$ rm ./src/main/obj/local/armeabi-v7a/libaudioboo-native.so
rob@ app$ rm ./src/main/jniLibs/armeabi-v7a/libaudioboo-native.so
Run Code Online (Sandbox Code Playgroud)
已解决的问题 - 将构建更改为以下内容仅使用./src/main/libs中的共享库
sourceSets {
main {
jni.srcDirs = [] /*disable automatic ndk-build call */
jniLibs.srcDir 'src/main/libs'
}
}
Run Code Online (Sandbox Code Playgroud)
在android5上打破了所以我通过为Android-studio(1.0)ndk build推文来解决它.我按照答案@holo的指示扫描了所有'findClass'的代码.注 - 在第34行更改了字符串常量
"fm.audioboo.jni.FLACStreamEncoder"; to "fm/audioboo/jni/FLACStreamEncoder";
Run Code Online (Sandbox Code Playgroud)
那并没有解决任何问题.
java代码调用一个函数,在该本机函数执行之前,看起来艺术框架本身就是在第二个arg中使用一个错误的char分隔符调用FindClass(_JNIEnv*,char const*).如果查看pastebin链接的第46-48行,它看起来就像调用本机函数一样.该框架只会抛出错误的包名称Findclass错误.请注意,本机函数的第一行是在运行时未到达的日志语句.
Java层......
public FLACStreamEncoder(String outfile, int sample_rate, int channels,
int bits_per_sample)
{
init(outfile, sample_rate, channels, bits_per_sample);
}
...
native private void init(String outfile, int sample_rate, int channels,
int bits_per_sample);
...
static {
System.loadLibrary("audioboo-native");
}
Run Code Online (Sandbox Code Playgroud)
CPP层...函数永远不会到达第一行日志stmt.
extern "C" {
void
Java_fm_audioboo_jni_FLACStreamEncoder_init(JNIEnv * env, jobject obj,
jstring outfile, jint sample_rate, jint channels, jint bits_per_sample)
{
aj::log(ANDROID_LOG_DEBUG, LTAG, "Begin INIT extern call");
assert(sizeof(jlong) >= sizeof(FLACStreamEncoder *));
FLACStreamEncoder * encoder = new FLACStreamEncoder(
aj::convert_jstring_path(env, outfile), sample_rate, channels,
bits_per_sample);
char const * const error = encoder->init();
if (NULL != error) {
delete encoder;
aj::throwByName(env, IllegalArgumentException_classname, error);
return;
}
set_encoder(env, obj, encoder);
}
Run Code Online (Sandbox Code Playgroud)
一切正常(jni build/android buid/android-java调用cpp)直到android 5使用ndk 10-C构建
android5/ART的新功能似乎是'check_jni.cc'和某种严格的模式给出错误:
D/FLACRecorder(26743): Setting up encoder /data/data/com.borneo.speech/files/20141123081747.flac rate: 22050 channels: 1 format 16
F/art (26743): art/runtime/check_jni.cc:65] JNI DETECTED ERROR IN APPLICATION: illegal class name 'fm.audioboo.jni.FLACStreamEncoder'
F/art (26743): art/runtime/check_jni.cc:65] (should be of the form 'package/Class', [Lpackage/Class;' or '[[B')
F/art (26743): art/runtime/check_jni.cc:65] in call to FindClass
F/art (26743): art/runtime/check_jni.cc:65] from void fm.audioboo.jni.FLACStreamEncoder.init(java.lang.String, int, int, int)
F
Run Code Online (Sandbox Code Playgroud)
完整的堆栈跟踪: 注意第46 - 48行
查看日志,就好像框架正在使用CPP中的第2个'thisClazz'arg对'findClass'进行OWN调用:
Java_fm_audioboo_jni_FLACStreamEncoder_init(JNIEnv * env, jobject obj, ...
Run Code Online (Sandbox Code Playgroud)
并且它违反艺术运行时检查的错误arg值.
但是我没有运行'javah'来创建java接口的任何头文件,因为它在我获得git项目之前就完成了.
我很难过.本机似乎进入函数,从未到达函数的第一行(log statemt),立即失败
/system/lib/libart.so (art::CheckJNI::FindClass(_JNIEnv*, char const*)+66
Run Code Online (Sandbox Code Playgroud)
ndk(R10C)链接cpp类如下:
make: Entering directory `/home/rob/tmp/audioboo-android/app/src/main/jni'
[armeabi-v7a] Compile thumb : audioboo-ogg <= bitwise.c
[armeabi-v7a] Compile thumb : audioboo-ogg <= framing.c
[armeabi-v7a] StaticLibrary : libaudioboo-ogg.a
[armeabi-v7a] Compile thumb : audioboo-flac <= bitmath.c
[armeabi-v7a] Compile thumb : audioboo-flac <= bitreader.c
[armeabi-v7a] Compile thumb : audioboo-flac <= cpu.c
[armeabi-v7a] Compile thumb : audioboo-flac <= crc.c
[armeabi-v7a] Compile thumb : audioboo-flac <= fixed.c
[armeabi-v7a] Compile thumb : audioboo-flac <= float.c
[armeabi-v7a] Compile thumb : audioboo-flac <= format.c
[armeabi-v7a] Compile thumb : audioboo-flac <= lpc.c
[armeabi-v7a] Compile thumb : audioboo-flac <= md5.c
[armeabi-v7a] Compile thumb : audioboo-flac <= memory.c
[armeabi-v7a] Compile thumb : audioboo-flac <= metadata_iterators.c
[armeabi-v7a] Compile thumb : audioboo-flac <= metadata_object.c
[armeabi-v7a] Compile thumb : audioboo-flac <= ogg_decoder_aspect.c
[armeabi-v7a] Compile thumb : audioboo-flac <= ogg_encoder_aspect.c
[armeabi-v7a] Compile thumb : audioboo-flac <= ogg_helper.c
[armeabi-v7a] Compile thumb : audioboo-flac <= ogg_mapping.c
[armeabi-v7a] Compile thumb : audioboo-flac <= stream_decoder.c
[armeabi-v7a] Compile thumb : audioboo-flac <= stream_encoder.c
[armeabi-v7a] Compile thumb : audioboo-flac <= stream_encoder_framing.c
[armeabi-v7a] Compile thumb : audioboo-flac <= window.c
[armeabi-v7a] Compile thumb : audioboo-flac <= bitwriter.c
[armeabi-v7a] StaticLibrary : libaudioboo-flac.a
[armeabi-v7a] Compile++ thumb: audioboo-native <= FLACStreamEncoder.cpp
[armeabi-v7a] Compile++ thumb: audioboo-native <= FLACStreamDecoder.cpp
[armeabi-v7a] Compile++ thumb: audioboo-native <= util.cpp
[armeabi-v7a] StaticLibrary : libstdc++.a
[armeabi-v7a] SharedLibrary : libaudioboo-native.so
[armeabi-v7a] Install : libaudioboo-native.so => libs/armeabi-v7a/libaudioboo-native.so
make: Leaving directory `/home/rob/tmp/audioboo-android/app/src/main/jni'
Run Code Online (Sandbox Code Playgroud)
Android加载了高于NP 的库audioboo-native然后抛出
JNI DETECTED ERROR IN APPLICATION: illegal class name 'fm.audioboo.jni.FLACStreamEncoder''
Run Code Online (Sandbox Code Playgroud)
从Java到本机函数的调用,我不明白为什么?
我在升级到Android 5时遇到了同样的问题,并且已经对它进行了排序.
该错误在您的本机代码中,而不在您的Java代码中.在您的本机代码中的某个位置,您有一个函数可以通过jni作为jobject传递FlacStreamEncoder对象,并使用以下行检索它:
jclass streamEncoder = env->FindClass("fm.audioboo.jni.FLACStreamEncoder");
但是JNI应该使用"/"作为分隔符而不是".",所以这一行应该是:
jclass streamEncoder = env->FindClass("fm/audioboo/jni/FLACStreamEncoder");
代替.以前版本的android默默地忽略了这个问题,但现在它只是在你脸上爆炸了.
从 https://android.googlesource.com/platform/art/+/kitkat-dev/runtime/check_jni.cc
// Checks that 'class_name' is a valid "fully-qualified" JNI class name, like "java/lang/Thread"
// or "[Ljava/lang/Object;". A ClassLoader can actually normalize class names a couple of
// times, so using "java.lang.Thread" instead of "java/lang/Thread" might work in some
// circumstances, but this is incorrect
void CheckClassName(const char* class_name) {
if (!IsValidJniClassName(class_name)) {
JniAbortF(function_name_,
"illegal class name '%s'\n"
" (should be of the form 'package/Class', [Lpackage/Class;' or '[[B')",
class_name);
}
}
}
| 归档时间: |
|
| 查看次数: |
6941 次 |
| 最近记录: |