android 打印 stderr
mark android 默认的 stderr 没有重定向到 logcat ,如果想在 logcat 上打印本地程序的错误信息,可以输入下列命令。 adb shell stop adb shell setprop log.redirect-stdio true adb shell start
mark android 默认的 stderr 没有重定向到 logcat ,如果想在 logcat 上打印本地程序的错误信息,可以输入下列命令。 adb shell stop adb shell setprop log.redirect-stdio true adb shell start
前面介绍了jni的基本概念和如何使用jni技术达到 Java 调用 C 的目的。 但是没有说 C 如何通过 jni 来调用 java 的方法,也就是如何实现回调。实现回调的作用很大,例如我们使用了 upnp 本地库,当库接收到消息便需要往 java 端传递。又例如使用了 C 实现了播放器,但是进度显示需要使用到 java。这些时候就需要用到回调了。 ##实现 先看看主要部分 :::java static void callback_handler(char *s) { int status; JNIEnv *env; bool isAttached = false; status = gJavaVM->GetEnv((void **) &env, JNI_VERSION_1_4); if(status < 0) { LOGE("callback_handler: failed to get JNI environment, " "assuming native thread"); status = gJavaVM->AttachCurrentThread(&env, NULL); if(status < 0) { LOGE("callback_handler: failed to attach " "current thread"); return; } isAttached = true; } /* Construct a Java string */ jstring js = env->NewStringUTF(s); jclass interfaceClass = env->GetObjectClass(gInterfaceObject); if(!...
在概述中基本搭建了一个jni的工程,但是有很多细节都没有讨论,这篇文件就是进一步讨论JNI技术的具体方面的,包括String的传递及使用,java的属性和方法的使用和异常抛出等。 String的使用 java的属性和方法 类的使用 异常抛出 ##String的使用 我们都知道JAVA有String这个类可以很方便地使用字符串,而在c中我们通常是用char*,那么JNI是怎么在这两种类型里转换的呢? 在之前的工程添加以下代码: :::c static JNINativeMethod gMethods[] = { {"intToJni","(I)V", (void*)nativeIntToJni}, {"conversation","(Ljava/lang/String;)Ljava/lang/String;", (void*)nativeConversation}, }; jstring nativeConversation(JNIEnv* env, jobject clazz, jstring fromJava){ const char* message; message = (*env)->GetStringUTFChars(env,fromJava,NULL); __android_log_print(ANDROID_LOG_INFO,"TAG","message from java: %s", message); (*env)->ReleaseStringUTFChars(env, fromJava, message); return (*env)->NewStringUTF(env, "nice to see you , i am c"); } 可以看到fromJava是从java传进来的string,message是jstring转换为char*的容器。使用方法GetStringUTFChars进行转换,使用ReleaseStringUTFChars释放资源。 Warning GetStringUTFChars和ReleaseStringUTFChars需要成对出现,要不会有内存泄漏的,native想保存字符串可以使用memcpy复制一份 顺便说说,貌似getStringRegion不用释放。对于JAVA的数组,也是不能直接使用的,需要做像String一样的处理。 JNI String 方法的汇总 JNI Function Description Since GetStringChars ReleaseStringChars Obtains or releases a pointer to the contents of a string in Unicode format....
JNI(Java Native Interface)是java调用本地代码的接口技术,基本上我是用它来在android中调用C/C++,android提供了一套套件叫做NDK(Native Development Kit),使我们可以很方便生成我们需要的目标文件。 专门有网站是介绍使用JNI的,网址是这里 ##使用举例 ###JAVA端实现 info 首先需要明确apk还是运行在Dalvik虚拟机中的,我们暂时还不能编写纯粹C/C++的应用,除非不需要面向用户界面 info 我们可以指定一个类来完成JAVA和C的交互工作,例如com.lingavin.jnisample.JavaToJni.java :::java package com.lingavin.jnsample; public class JavaToJni { static{ //系统加载 libnativejni.so System.loadLibrary("nativejni"); } //对应native函数的接口,用native关键字来修饰 public static native void intToJni(int number); } 就这样一个简单的JAVA端部分完成了,程序通过调用JavaToJni.intToJni(num),就可以将int传入C/C++处理。 ###native端实现 native端的实现才是重点内容,本次使用动态注册的方式和C语言来完成这项工作。 info jni本地代码的接口分为动态注册和静态注册,本文只体现动态注册 info info 要注意用C和用C++写jni接口是有些区别的,主要是方法调用上,C调用env方法是(*env)->xxx(env,xxx),C++则为env->xxx(xxx) info 在本工程中创建一个jni/目录,进去后创建native_sample_jni.c,我们将在这个文件中完成代码编写。开始是JNI_OnLoad函数。 info JNI_OnLoad函数是必须要的,系统就是从这个函数开始注册工作的。这个可以被看做回调函数 info :::c JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved){ JNIEnv* env = NULL; jint result = -1; if((*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_4) != JNI_OK){ return result; } if(!registerNatives(env)){ return result; } result = JNI_VERSION_1_4; return result; } 看到JNI_OnLoad函数中调用了registerNatives函数,那就看看这个函数干了些什么。...