javah是用来干嘛的呢?
它是用来生成C语音的头文件的。
通过一个helloworld看一下 javah的作用吧:
原来我们新建一个项目后,自己写C代码:
#include <stdio.h> #include <jni.h> jstring Java_com_itheima15_ndk1_MainActivity_helloFromJNI(JNIEnv* env, jobject obj){ //输出一个java字符串 //返回一个java字符串 //jstring (*NewStringUTF)(JNIEnv*, const char*); char* cstr = "helloFromJNI"; return (**env).NewStringUTF(env, cstr); }
jstring Java_com_itheima15_ndk1_MainActivity_helloFromJNI(JNIEnv* env, jobject obj)这个方法名要自己写,挺费劲吧,就算C++功底还算不错,写出一个,如果真到项目中,我们java中使用到了十几甚至几十个c方法,那就真的hi有的忙活了
javah就是给我们自动生成这玩意儿用的
下面介绍下使用方法:
新建一个android项目,我们先写布局和activity
布局,老规矩:一个按钮
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:text="调用C代码" android:onClick="click" /> </RelativeLayout>
import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.Toast; public class MainActivity extends Activity { static{ System.loadLibrary("Hello"); } public native String hello(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void click(View view){ //调用c代码 Toast.makeText(this, hello(), 0).show(); } }
这个需要注意jdk1.6以下版本和jdk1.7版本是有一点不一样的
先说1.6版本
进入我们工程的bin目录下:执行 javah -jni + 写了调用c方法的那个类的class文件
而1.7版本呢
进入我们工程的src目录下:执行 javah -jni + 写了调用c方法的那个类
然后到对应文件夹下就会生成一个对应的 h 文件
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class com_test_MainActivity */ #ifndef _Included_com_test_MainActivity #define _Included_com_test_MainActivity #ifdef __cplusplus extern "C" { #endif /* * Class: com_test_MainActivity * Method: hello * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_test_MainActivity_hello (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif
开始根据这个头文件来写对应的c文件
#include <jni.h>
#include "com_test_MainActivity.h"//引入生成的头文件
#include <android/log.h>
#define LOG_TAG "System.out"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
JNIEXPORT jstring JNICALL Java_com_test_MainActivity_hello
(JNIEnv * env, jobject obj){
//NewStringUTF()
//return (**env).NewStringUTF(env, "您好 jni");
LOGI("hello");
LOGI("1");
LOGI("2");
return (**env).NewStringUTF(env, "您好 jni");
LOGI("3");
}