JNI C调用Java
1、在Java里写好要被C调用的方面
public class JNI {
private static final String TAG = "JNI";
static {
// 静态初始化代码块,这里加载的库名称要和 gradle 中定义的 moduleName 名称一致
System.loadLibrary("CCallJava");
}
// D:\app\android\TestNdk\ccalljava\build\intermediates\classes\debug
public static native void callbackAdd();
public static native void callbackSayHello();
public static native void callbackStaticSayHello();
public static native void callbackIncreaseArayEles();
public static native void callbackCheckPwd();
public int add(int var1, int var2) {
Log.i(TAG, "add: var1 =" + var1);
Log.i(TAG, "add: var2 =" + var2);
return var1 + var2;
}
public void sayHello(String var1) {
Log.i(TAG, "sayHello: var1 = " + var1);
}
public static void sayStaticHello(String var1) {
Log.i(TAG, " static sayHello: var1 = " + var1);
}
public int[] increaseArayEles(int[] var1) {
Log.i(TAG, "increaseArayEles: ");
int[] aa = new int[10];
return aa;
}
public int checkPwd(String var1) {
Log.i(TAG, "checkPwd: ");
return 0;
}
}
2、使用 命令行生成被C调用的方法的签名
D:\app\android\TestNdk\ccalljava\build\intermediates\classes\debug>javap -s com.lwb.ccalljava.JNI
3、使用javah生成头文件D:\app\android\TestNdk\ccalljava\build\intermediates\classes\debug>javap -s com.lwb.ccalljava.JNI Compiled from "JNI.java" public class com.lwb.ccalljava.JNI { public com.lwb.ccalljava.JNI(); Signature: ()V public static native void callbackAdd(); Signature: ()V public static native void callbackSayHello(); Signature: ()V public static native void callbackIncreaseArayEles(); Signature: ()V public static native void callbackCheckPwd(); Signature: ()V public int add(int, int); Signature: (II)I public void syHello(java.lang.String); Signature: (Ljava/lang/String;)V public int[] increaseArayEles(int[]); Signature: ([I)[I public int checkPwd(java.lang.String); Signature: (Ljava/lang/String;)I static {}; Signature: ()V }
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_lwb_ccalljava_JNI */
/* 要使用Log则需要引用 android/log.h 这个头文件 */
#include <android/log.h>
/* 可以根据需要调用不同类型的 LOG */
#ifndef LOG_TAG
#define LOG_TAG "ANDROID_LOG"
#define LOG_E(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG , __VA_ARGS__)
#define LOG_I(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG , __VA_ARGS__)
#define LOG_W(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG , __VA_ARGS__)
#define LOG_D(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG , __VA_ARGS__)
#endif
#ifndef _Included_com_lwb_ccalljava_JNI
#define _Included_com_lwb_ccalljava_JNI
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_lwb_ccalljava_JNI
* Method: callbackAdd
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_lwb_ccalljava_JNI_callbackAdd
(JNIEnv *, jclass);
/*
* Class: com_lwb_ccalljava_JNI
* Method: callbackSayHello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_lwb_ccalljava_JNI_callbackSayHello
(JNIEnv *, jclass);
/*
* Class: com_lwb_ccalljava_JNI
* Method: callbackStaticSayHello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_lwb_ccalljava_JNI_callbackStaticSayHello
(JNIEnv *, jclass);
/*
* Class: com_lwb_ccalljava_JNI
* Method: callbackIncreaseArayEles
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_lwb_ccalljava_JNI_callbackIncreaseArayEles
(JNIEnv *, jclass);
/*
* Class: com_lwb_ccalljava_JNI
* Method: callbackCheckPwd
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_lwb_ccalljava_JNI_callbackCheckPwd
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
4、编写.c文件(涉及到 反射、 方法的签名)
#include "com_lwb_ccalljava_JNI.h"
#include <stdlib.h>
#include <stdio.h>
JNIEXPORT void JNICALL
Java_com_lwb_ccalljava_JNI_callbackAdd
(JNIEnv
*env ,
jclass jcls
){
LOG_I ("log 类型 _I111");
//1、得到字节码
// jclass (*FindClass)(JNIEnv*, const char*);
jclass jclazz = (*env)->FindClass(env, "com/lwb/ccalljava/JNI");
LOG_I ("log 类型 _I222");
//得到方法
// jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
jmethodID method = (*env)->GetMethodID(env, jclazz, "add", "(II)I");
LOG_I ("log 类型 _I333");
//实例化该类 jobject (*AllocObject)(JNIEnv*, jclass);
jobject jobject = (*env)->AllocObject(env, jclazz);
LOG_I ("log 类型 _I44");
//调用方法
// jint (*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...);
jint ji = (*env)->CallIntMethod(env, jobject, method, 99, 110);
LOG_I ("log 类型 _I55 %d", ji);
};
JNIEXPORT void JNICALL Java_com_lwb_ccalljava_JNI_callbackSayHello
(JNIEnv * env , jclass jcls){
LOG_I ("log 类型 _I111");
//1、得到字节码
// jclass (*FindClass)(JNIEnv*, const char*);
jclass jclazz = (*env)->FindClass(env, "com/lwb/ccalljava/JNI");
LOG_I ("log 类型 _I222");
//得到方法
// jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
jmethodID method = (*env)->GetMethodID(env, jclazz, "sayHello", "(Ljava/lang/String;)V");
LOG_I ("log 类型 _I333");
//实例化该类 jobject (*AllocObject)(JNIEnv*, jclass);
jobject jobject = (*env)->AllocObject(env, jclazz);
LOG_I ("log 类型 _I44");
//调用方法
// jint (*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...);
jstring jstr = (**env).NewStringUTF(env,"sayhello 00000");
(*env)->CallVoidMethod(env, jobject, method,jstr);
LOG_I ("log 类型 _I55");
};
JNIEXPORT void JNICALL Java_com_lwb_ccalljava_JNI_callbackStaticSayHello
(JNIEnv * env , jclass jcls){
LOG_I ("log 类型 _I111");
//1、得到字节码
// jclass (*FindClass)(JNIEnv*, const char*);
jclass jclazz = (*env)->FindClass(env, "com/lwb/ccalljava/JNI");
LOG_I ("log 类型 _I222");
//得到方法
// jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
jmethodID method = (*env)->GetStaticMethodID(env, jclazz, "sayStaticHello", "(Ljava/lang/String;)V");
LOG_I ("log 类型 _I333");
//实例化该类 jobject (*AllocObject)(JNIEnv*, jclass);
//jobject jobject = (*env)->AllocObject(env, jclazz);
//LOG_I ("log 类型 _I44");
//调用方法
// void (*CallStaticVoidMethod)(JNIEnv*, jclass, jmethodID, ...);
jstring jstr = (**env).NewStringUTF(env,"static sayhello 111");
(*env)->CallStaticVoidMethod(env, jclazz, method,jstr);
LOG_I ("log 类型 _I55");
};
4、Android 测试用例
ublic class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void add(View view) {
// JNI.callbackAdd();
JNI.callbackStaticSayHello();
}
public void syHello(View view) {
// String result = JNI.syHello("from java");
// Log.i(TAG, "syHello: result = " + result);
JNI. callbackSayHello();
}
public void increaseArayEles(View view) {
// int[] var1 = new int[10];
// for (int i = 0; i < var1.length; i++) {
// var1[i] = i;
// }
// int[] result = JNI.increaseArayEles(var1);
// for (int i = 0; i < result.length; i++) {
// Log.i(TAG, "syHello: result = " + result[i]);
// }
}
public void checkPwd(View view) {
// int result = JNI.checkPwd("123456");
//
// Log.i(TAG, "syHello: result = " + result);
}
}