- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我无法从我的 Android 应用程序的 native 部分回调 Java(Kotlin)。这是一个音频应用程序,所以你会看到“很多音频”这个词,但我认为问题与此无关。
我已经阅读了很多文章并对此进行了几天的实验,但我无法解决我的问题。我可以从我的 native_lib.cpp
触发我的 java 回调。 ,所以我已经测试了所有这些,并且我的 JniBridge
之间的方法引用我的 native 代码应该是正确的。
但是我想从一个单独的类中完成它,而且我还必须能够从不同的线程中多次完成它。所以我想尽可能永久地存储我对 JVM 回调类的引用,但我没有做对。
我当前的代码因以下错误而失败:
A: java_vm_ext.cc:542] JNI DETECTED ERROR IN APPLICATION: JNI GetMethodID called with pending exception java.lang.ClassNotFoundException: Didn't find class "com.my.app.common.jni.JniBridge" on path: DexPathList[[directory "."],nativeLibraryDirectories=[/system/lib64, /system/vendor/lib64, /system/lib64, /system/vendor/lib64]]
A: java_vm_ext.cc:542] at java.lang.Class dalvik.system.BaseDexClassLoader.findClass(java.lang.String) (BaseDexClassLoader.java:134)
A: java_vm_ext.cc:542] at java.lang.Class java.lang.ClassLoader.loadClass(java.lang.String, boolean) (ClassLoader.java:379)
A: java_vm_ext.cc:542] at java.lang.Class java.lang.ClassLoader.loadClass(java.lang.String) (ClassLoader.java:312)
A: java_vm_ext.cc:542]
A: java_vm_ext.cc:542] in call to GetMethodID
A: java_vm_ext.cc:542] "Thread-6" prio=10 tid=17 Runnable
A: java_vm_ext.cc:542] | group="main" sCount=0 dsCount=0 flags=0 obj=0x13080000 self=0x7ca400e800
A: java_vm_ext.cc:542] | sysTid=30175 nice=-16 cgrp=default sched=1073741825/2 handle=0x7c911014f0
A: java_vm_ext.cc:542] | state=R schedstat=( 5738847 149269 9 ) utm=0 stm=0 core=1 HZ=100
A: java_vm_ext.cc:542] | stack=0x7c91006000-0x7c91008000 stackSize=1009KB
A: java_vm_ext.cc:542] | held mutexes= "mutator lock"(shared held)
A: java_vm_ext.cc:542] native: #00 pc 00000000003cb654 /system/lib64/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char>>&, int, BacktraceMap*, char const*, art::ArtMethod*, void*, bool)+220)
#include <jni.h>
class AudioCallback {
public:
explicit AudioCallback(JavaVM&, jobject&);
void playBackProgress(int progressPercentage);
private:
JavaVM& mJvm;
jobject& mObject;
};
#include <jni.h>>
#include <utils/logging.h>
#include "AudioCallback.h"
AudioCallback::AudioCallback(JavaVM &jvm, jobject &object) : mJvm(jvm), mObject(object) {
}
void AudioCallback::playBackProgress(int progressPercentage) {
JNIEnv *g_env = NULL;
int getEnvStat = mJvm.GetEnv((void **) &g_env, JNI_VERSION_1_6);
JavaVMAttachArgs vmAttachArgs;
vmAttachArgs.version = JNI_VERSION_1_6;
vmAttachArgs.name = NULL;
vmAttachArgs.group = NULL;
if (getEnvStat == JNI_EDETACHED) {
LOGD("GetEnv: not attached - attaching");
if (mJvm.AttachCurrentThread(&g_env, &vmAttachArgs) != 0) {
LOGD("GetEnv: Failed to attach");
}
} else if (getEnvStat == JNI_OK) {
LOGD("GetEnv: JNI_OK");
} else if (getEnvStat == JNI_EVERSION) {
LOGD("GetEnv: version not supported");
}
if (g_env != NULL) {
jclass target = g_env->FindClass("com/my/app/common/jni/JniBridge");
jmethodID id = g_env->GetMethodID(target, "integerCallback", "(I)V");
g_env->CallVoidMethod(mObject, id, (jint) progressPercentage);
} else {
LOGE("JNIEnv is null!");
mJvm.DetachCurrentThread();
}
}
native_lib.cpp
,我在
JNI_OnLoad
中获得了 JavaVM像这样:
JavaVM *jvm;
jint JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv jvm_env;
int getEnvStatus = vm->GetEnv((void **) &jvm_env, JNI_VERSION_1_6);
if (getEnvStatus != JNI_OK) {
LOGE("JNI_ONLOAD Failed to get the environment using GetEnv()");
return -1;
}
jvm = vm;
if (jvm == NULL) {
LOGE("JNI_ONLOAD: globabl jvm is NULL");
} else {
LOGD("JNI_ONLOAD: global jvm is NOT NULL");
}
LOGD("Onload done");
return JNI_VERSION_1_6;
}
AudioEngine
使用它的类:
JNIEXPORT void JNICALL
Java_com_my_app_common_jni_JniBridge_playFromJNI(JNIEnv *env, jobject instance,jstring URI) {
// Here I instantiate my callback
callback = std::make_unique<AudioCallback>(*jvm, instance);
// below code sets up my audio engine class, which calls the AudioCallback during playback.
// This works without problems.
const char *uri = env->GetStringUTFChars(URI, NULL);
AMediaExtractor *extractor = AMediaExtractor_new();
if (extractor == nullptr) {
LOGE("Could not obtain AMediaExtractor");
return;
}
media_status_t amresult = AMediaExtractor_setDataSource(extractor, uri);
if (amresult != AMEDIA_OK) {
LOGE("Error setting extractor data source, error %d", amresult);
}
audioEngine = std::make_unique<AudioEngine>(*extractor, *callback);
audioEngine->setFileName(uri);
audioEngine->start();
}
audioEngine
使用
oboe用于音频处理的库,因此我无法控制其中可能的线程创建,因此
AttachCurrentThread()
在我的回调类中。附加和分离工作,唯一失败的是对 Java 的回调。
最佳答案
我主要自己解决了这个问题(阅读评论中@Michael的建议以及那里提到的其他一些地方肯定有帮助!):
首先,我将“设置”部分与实际的回调函数分开(这一直是计划,但不这样做会妨碍看到问题)。
二、在我的native_lib.cpp
我创建了一个对我的 jobject
的全局引用(问题示例中 playFromJNI
中的“实例”对象),然后将其传递给 AudioCallback's
像这样的构造函数:
myJNIClass = env->NewGlobalRef(instance);
callback = std::make_unique<AudioCallback>(*g_jvm, myJNIClass);
playbackProgress
我只在必要时处理 ÀttachToCurrentThread ,并使用我事先用正确数据初始化的类成员。
AudioCallback
实现现在看起来像:
#include <jni.h>>
#include <utils/logging.h>
#include "AudioCallback.h"
jclass target;
jmethodID id;
AudioCallback::AudioCallback(JavaVM &jvm, jobject object) : g_jvm(jvm), g_object(object) {
JNIEnv *g_env;
int getEnvStat = g_jvm.GetEnv((void **) &g_env, JNI_VERSION_1_6);
LOGD("Env Stat: %d", getEnvStat);
if (g_env != NULL) {
target = g_env->GetObjectClass(g_object);
id = g_env->GetMethodID(target, "integerCallback", "(I)V");
}
}
void AudioCallback::playBackProgress(int progressPercentage) {
JNIEnv *g_env;
int getEnvStat = g_jvm.GetEnv((void **) &g_env, JNI_VERSION_1_6);
if (getEnvStat == JNI_EDETACHED) {
LOGD("GetEnv: not attached - attaching");
if (g_jvm.AttachCurrentThread(&g_env, NULL) != 0) {
LOGD("GetEnv: Failed to attach");
}
} else if (getEnvStat == JNI_OK) {
LOGD("GetEnv: JNI_OK");
} else if (getEnvStat == JNI_EVERSION) {
LOGD("GetEnv: version not supported");
}
g_env->CallVoidMethod(g_object, id, (jint) progressPercentage);
}
关于c++ - 如何解决 "Didn' t 在路径 : DexPathList in my native callback to Java 上找到类 "...",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61168825/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!