在NDK C++线程中如何调用JAVA API
2015-02-27 15:57
453 查看
from://http://www.eoeandroid.com/thread-150995-1-1.html
在NDK中创建的线程中, 只允许调用静态的Java API. 当在线程中调用env->FindClass(), 系统就会发出异常.
http://android.wooyd.org/JNIExample中有较详细的调用说明.
示例代码如下:
JAVA 代码:
public class simple_test extends Activity {
...
public static void PrintNdkLog(String slog) {
Log.e("NDK", slog);
}
}
C++ 代码:
static JavaVM* g_JavaVM = NULL;
static jobject g_InterfaceObject = 0;
static void GetInterfaceObject(JNIEnv *env, const char *path, jobject *objptr) {
jclass cls = env->FindClass(path);
if(!cls) {
return;
}
jmethodID constr = env->GetMethodID(cls, "<init>", "()V");
if(!constr) {
return;
}
jobject obj = env->NewObject(cls, constr);
if(!obj) {
return;
}
(*objptr) = env->NewGlobalRef(obj);
}
int JniLoad(JavaVM* jvm, void* reserved)
{
g_JavaVM = jvm;
JNIEnv *env;
if (jvm->GetEnv((void**) &env, JNI_VERSION_1_6) != JNI_OK) {
return -1;
}
GetInterfaceObject(env, "com/myndk/simple_test", &g_InterfaceObject);
return JNI_VERSION_1_6;
}
void JniUnLoad(JavaVM* jvm, void* reserved)
{
JNIEnv *env;
if (jvm->GetEnv((void**) &env, JNI_VERSION_1_6) != JNI_OK) {
return;
}
env->DeleteGlobalRef(g_InterfaceObject);
}
void PrintNdkLog(const char *format, ...)
{
va_list arg_ptr;
char sLogBuff[1024];
va_start(arg_ptr, format);
vsprintf(sLogBuff, format, arg_ptr);
va_end(arg_ptr);
if (g_JavaVM == NULL)
return;
int status;
JNIEnv *env = NULL;
bool isAttached = false;
status = g_JavaVM->GetEnv((void**) &env, JNI_VERSION_1_6);
if(status < 0)
{
status = g_JavaVM->AttachCurrentThread(&env, NULL);
if(status < 0)
{
return;
}
isAttached = true;
}
jclass cls = env->GetObjectClass(g_InterfaceObject);
if (cls != 0)
{
jmethodID mid = env->GetStaticMethodID(cls, "PrintNdkLog", "(Ljava/lang/String;)V");
if (mid != 0)
{
jstring jstrMSG = env->NewStringUTF(sLogBuff);
env->CallStaticVoidMethod(cls, mid, jstrMSG);
}
}
if (isAttached) // From native thread
{
g_JavaVM->DetachCurrentThread();
}
}
在NDK中创建的线程中, 只允许调用静态的Java API. 当在线程中调用env->FindClass(), 系统就会发出异常.
http://android.wooyd.org/JNIExample中有较详细的调用说明.
示例代码如下:
JAVA 代码:
public class simple_test extends Activity {
...
public static void PrintNdkLog(String slog) {
Log.e("NDK", slog);
}
}
C++ 代码:
static JavaVM* g_JavaVM = NULL;
static jobject g_InterfaceObject = 0;
static void GetInterfaceObject(JNIEnv *env, const char *path, jobject *objptr) {
jclass cls = env->FindClass(path);
if(!cls) {
return;
}
jmethodID constr = env->GetMethodID(cls, "<init>", "()V");
if(!constr) {
return;
}
jobject obj = env->NewObject(cls, constr);
if(!obj) {
return;
}
(*objptr) = env->NewGlobalRef(obj);
}
int JniLoad(JavaVM* jvm, void* reserved)
{
g_JavaVM = jvm;
JNIEnv *env;
if (jvm->GetEnv((void**) &env, JNI_VERSION_1_6) != JNI_OK) {
return -1;
}
GetInterfaceObject(env, "com/myndk/simple_test", &g_InterfaceObject);
return JNI_VERSION_1_6;
}
void JniUnLoad(JavaVM* jvm, void* reserved)
{
JNIEnv *env;
if (jvm->GetEnv((void**) &env, JNI_VERSION_1_6) != JNI_OK) {
return;
}
env->DeleteGlobalRef(g_InterfaceObject);
}
void PrintNdkLog(const char *format, ...)
{
va_list arg_ptr;
char sLogBuff[1024];
va_start(arg_ptr, format);
vsprintf(sLogBuff, format, arg_ptr);
va_end(arg_ptr);
if (g_JavaVM == NULL)
return;
int status;
JNIEnv *env = NULL;
bool isAttached = false;
status = g_JavaVM->GetEnv((void**) &env, JNI_VERSION_1_6);
if(status < 0)
{
status = g_JavaVM->AttachCurrentThread(&env, NULL);
if(status < 0)
{
return;
}
isAttached = true;
}
jclass cls = env->GetObjectClass(g_InterfaceObject);
if (cls != 0)
{
jmethodID mid = env->GetStaticMethodID(cls, "PrintNdkLog", "(Ljava/lang/String;)V");
if (mid != 0)
{
jstring jstrMSG = env->NewStringUTF(sLogBuff);
env->CallStaticVoidMethod(cls, mid, jstrMSG);
}
}
if (isAttached) // From native thread
{
g_JavaVM->DetachCurrentThread();
}
}
相关文章推荐
- NDK C++线程中如何调用JAVA API
- java中如何使用JNI调用C++写的函数
- 如何在C/C++中调用Java
- 如何在C/C++中调用Java
- chap 17:当JNI遇到多线程--java对象如何被C++中的多个线程访问?
- Android-NDK开发之基础--Android JNI实例代码(一)-- 在JNI中执行Java方法--C/C++调用Java
- JAVA如何调用C/C++方法
- 如何用java调用c++编写成的DLL
- 当JNI遇到多线程--java对象如何被C++中的多个线程访问?
- 如何在C/C++中调用Java的方法
- Chap14:如何在C/C++中调用Java
- 请教:在java中如何实现线程的函数互斥调用,用synchronized好像实现不了
- 如何在C/C++中调用Java
- C++调用PythonAPI线程状态和全局解释器锁
- Android-NDK开发之基础--Android JNI实例代码(一)-- 在JNI中执行Java方法--C/C++调用Java
- Android-NDK开发之基础--Android JNI实例代码(一)-- 在JNI中执行Java方法--C/C++调用Java
- 如何动态调用之Java脚本API
- C++调用PythonAPI线程状态和全局解释器锁
- C++.net如何跨线程调用windows控件
- 如何在C/C++中调用Java的方法