1.Jni层调用java层函数,产生回调
2.数组在C/C++层、jni层、java层之间的传递
3.C/C++层、jni层、java之间函数的调用与参数的传递
4.C++面向对象
5.使用JNI_OnLoad
package com.example.test1;
//javah com.example.test.XTNative 生成jni层的.h文件
public class XTNative
{
static {
try {
System.loadLibrary("a");
System.loadLibrary("b");
System.loadLibrary("Test1");
} catch (UnsatisfiedLinkError e) {
// TODO: handle exception
e.printStackTrace();
}
}
public static native void XTSetMainHwnd(long mhwnd);//传入long类型参数
public static native String XTSetMainHwnd();//返回String类型
public static native long getLongName(long mhwnd);//返回long类型
//传入一个接口,让jni层调用java层的函数,并且回调在Java层使用参数
public static native void setCallbackOnTellLocalIDs(JKCallBack oncj,int a, int b);
public static native void operateArray(int []array,int length);//传入数组
public static native void operateString(String string);//传入String类型参数
public static native int[] operateIntArray(int []array,int length);//传入数组,返回数组
}
package com.example.test1;
public interface JKCallBack {
void callback(int a,int b);
void callback(int a,int b, int c);
}
package com.example.test1;
import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivityextends Activity implements JKCallBack{
View view;
Button button;
int []array = {1,52,441,63,55};
int []JniArray;
GLSurfaceView a;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_item);
XTNative.XTSetMainHwnd(100000000);
System.out.println("+++++" + XTNative.XTSetMainHwnd());
System.out.println("+++++" + XTNative.getLongName(520));
XTNative.setCallbackOnTellLocalIDs(this, 10, 20);
XTNative.operateArray(array,array.length);
XTNative.operateString("chenhanhere");
JniArray = XTNative.operateIntArray(array,array.length);
for(int i = 0; i <JniArray.length; i++){
System.out.println("+++++" +JniArray[i]);
}
}
@Override
public void callback(int a,int b)
{
// TODO 自动生成的方法存根
System.out.println("vadaweeeeaa:" + (a+b));
}
@Override
public void callback(int a,int b, int c)
{
// TODO 自动生成的方法存根
System.out.println("a b c :" + (a+b));
}
}
com_example_test1_XTNative.h
#include <jni.h>
/* Header for class com_example_test1_XTNative */
#ifndef _Included_com_example_test1_XTNative
#define _Included_com_example_test1_XTNative
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_example_test1_XTNative
* Method: XTSetMainHwnd
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_com_example_test1_XTNative_XTSetMainHwnd__J
(JNIEnv *, jclass, jlong);
/*
* Class: com_example_test1_XTNative
* Method: XTSetMainHwnd
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_example_test1_XTNative_XTSetMainHwnd__
(JNIEnv *, jclass);
/*
* Class: com_example_test1_XTNative
* Method: getLongName
* Signature: (J)J
*/
JNIEXPORT jlong JNICALL Java_com_example_test1_XTNative_getLongName
(JNIEnv *, jclass, jlong);
/*
* Class: com_example_test1_XTNative
* Method: setCallbackOnTellLocalIDs
* Signature: (Lcom/example/test1/JKCallBack;II)V
*/
JNIEXPORT void JNICALL Java_com_example_test1_XTNative_setCallbackOnTellLocalIDs
(JNIEnv *, jclass, jobject, jint, jint);
/*
* Class: com_example_test1_XTNative
* Method: operateArray
* Signature: ([II)V
*/
JNIEXPORT void JNICALL Java_com_example_test1_XTNative_operateArray
(JNIEnv *, jclass, jintArray, jint);
/*
* Class: com_example_test1_XTNative
* Method: operateString
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_com_example_test1_XTNative_operateString
(JNIEnv *, jclass, jstring);
/*
* Class: com_example_test1_XTNative
* Method: operateIntArray
* Signature: ([II)[I
*/
JNIEXPORT jintArray JNICALL Java_com_example_test1_XTNative_operateIntArray
(JNIEnv *, jclass, jintArray, jint);
#ifdef __cplusplus
}
#endif
#endif
Test1.cpp
#include <jni.h>
#include "com_example_test1_XTNative.h"
#include <android/log.h>
#include <string.h>
#include "inc/a.h"
#include "inc/incjia/b.h"
void JNICALL Java_com_example_test1_XTNative_XTSetMainHwnd__J
(JNIEnv * env, jclass cls, jlong mhwnd){
int i = 50;
__android_log_print(4, "test_xt", "mhwnd:%d", i);
__android_log_print(4,"OnLinkServer_callback","sNum=%d,bz=%d",i,i);
}
jstring JNICALL Java_com_example_test1_XTNative_XTSetMainHwnd__
(JNIEnv * env, jclass cls){
jstring szsIDS=env->NewStringUTF("AAAAAA");
return szsIDS;
}
jlong JNICALL Java_com_example_test1_XTNative_getLongName
(JNIEnv * env, jclass cls, jlong mhwnd){
long pwd = mhwnd + 700;
return pwd;
}
void JNICALL Java_com_example_test1_XTNative_setCallbackOnTellLocalIDs
(JNIEnv * env, jclass cls, jobject obj, jint a, jint b){
jclass jls = env->GetObjectClass(obj);//获得传入的obj
__android_log_print(4, "call", "back");
jmethodID callback = env->GetMethodID(jls, "callback", "(III)V");//获得obj里面的callback方法
env->CallVoidMethod(obj, callback, a, add(a, b));//返回java层调用函数的参数
__android_log_print(4, "call", "back");
printHello();
}
void JNICALL Java_com_example_test1_XTNative_operateArray
(JNIEnv * env, jclass cls, jintArray array, jint length){
__android_log_print(4, "array", "length=%d", length);
jint nativeaArray[length];
env->GetIntArrayRegion(array, 0, length, nativeaArray);
//env->ReleaseIntArrayElements(array, nativeaArray, 0);
for(int i = 0; i < length; i++) {
__android_log_print(4, "array", "nativeaArray[%d]=%d", i, nativeaArray[i]);
}
}
void JNICALL Java_com_example_test1_XTNative_operateString
(JNIEnv * env, jclass cls, jstring str){
int a = env->GetStringLength(str);
jboolean isCopy = true;
int c = min(100, 50);
const jchar *chars = env->GetStringChars(str, &isCopy);
__android_log_print(4, "aaa", "str length = %d", a);
__android_log_print(4, "aaa", "chars = %s", chars);
}
jintArray JNICALL Java_com_example_test1_XTNative_operateIntArray
(JNIEnv * env, jclass cls , jintArray array, jint length){
jint nativeaArray[length];
env->GetIntArrayRegion(array, 0, length, nativeaArray);
arrayC(nativeaArray, length);
for(int i = 0; i < length; i++) {
nativeaArray[i] = 1 + nativeaArray[i];
__android_log_print(4, "array", "nativeaArray[%d]=%d", i, nativeaArray[i]);
}
env->SetIntArrayRegion(array, 0, length, nativeaArray);
Light *led = LightNew();
led->turnOn(led);
led->turnOff(led);
__android_log_print(4, "led", "led status=%d", led->state);
//env->ReleaseIntArrayElements(array, nativeaArray, 0);
Student stu;
stu.age = 100;
__android_log_print(4, "Student", "Student age=%d", stu.age);
stu.say(stu);
return array;
}
Android.mk
LOCAL_PATH := $(call my-dir)
JNI_PATH := $(LOCAL_PATH)
include $(CLEAR_VARS)
LOCAL_MODULE := Test1
LOCAL_SRC_FILES := Test1.cpp
LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -L$(ANDROID_LIB)/ -llog -landroid
LOCAL_SHARED_LIBRARIES := a b
include $(BUILD_SHARED_LIBRARY)
include $(JNI_PATH)/inc/Android.mk
include $(JNI_PATH)/inc/incjia/Android.mk
a.h
/*
* a.h
*
* Created on: 2016年6月14日
* Author: chenhan
*/
#ifndef C_H_
#define C_H_
#include <stdio.h>
#include <malloc.h>
void printHello();
int add(int a,int b);
void printChars(char *chars);
int min(int a,int b);
int *arrayOperate(int arr[],int length);
void arrayC(int *p,int length);
struct Light
{
int state;
void (*turnOn)(Light*);
void (*turnOff)(Light*);
};
typedef struct Light Light;
static void turnOn(Light *cobj);
static void turnOff(Light *cobj);
struct Light *LightNew();
#endif /* C_H_ */
a.cpp
#include "a.h"
#include <android/log.h>
void printHello(){
__android_log_print(4, "printHello", "printHello");
}
int add(int a,int b){
return (a*b);
}
void printChars(char *chars){
__android_log_print(4, "char", "");
}
int min(int a,int b){
return (a-b);
}
int *arrayOperate(int arr[],int length){
for(int i = 0; i < length; i++){
arr[i] = arr[i] + 100;
}
return arr;
}
void arrayC(int *p,int length){
for(int i = 0; i < length; i++){
__android_log_print(4, "array", "+++++%d", p[i]);
p[i] = p[i] + 100;
}
}
static void turnOn(Light *cobj)
{
cobj->state = 1;
__android_log_print(4, "array", "+++++on++%d", cobj->state);
}
static void turnOff(Light *cobj)
{
cobj->state = 0;
__android_log_print(4, "array", "+++++off++%d", cobj->state);
}
struct Light *LightNew()
{
// 構造式
struct Light *t;
t = (Light *)malloc(sizeof(Light));
t->turnOn = turnOn;
t->turnOff = turnOff;
return t;
}
a对应的Android.mk文件
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := a
LOCAL_SRC_FILES := a.cpp
LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -L$(ANDROID_LIB)/ -llog -landroid
include $(BUILD_SHARED_LIBRARY)
b.h
/*
* b.h
*
* Created on: 2016年8月18日
* Author: chenhan
*/
#ifndef B_H_
#define B_H_
#include <stdio.h>
typedef void Student_Say;
class Student {
public :
int age;
int source;
public :
Student_Say say(Student stu);
};
#endif /* B_H_ */
b.cpp
/*
* b.cpp
*
* Created on: 2016年8月18日
* Author: chenhan
*/
#include "b.h"
#include <android/log.h>
Student_Say Student::say(Student stu)
{
__android_log_print(4, "C++ printHello","C++ say Hello + %d", stu.age);
}
b对应的Android.mk文件
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := b
LOCAL_SRC_FILES := b.cpp
LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -L$(ANDROID_LIB)/ -llog -landroid
include $(BUILD_SHARED_LIBRARY)
//在Test1.cpp文件加上如下代码可以不需要com_example_test1_XTNative.h文件
JavaVM* g_vm;
static JNINativeMethod gMethods[] = {
{"XTSetMainHwnd", "(J)", (void *)XTSetMainHwnd},
{"XTSetMainHwnd","()Ljava/lang/String;",(void*)XTSetMainHwnd},
{"getLongName","(J)J",(void*)getLongName},
{"setCallbackOnTellLocalIDs","(Lcom/example/test1/JKCallBack;II)V",(void*)setCallbackOnTellLocalIDs},
{"operateArray","([II)V",(void*)operateArray},
{"operateString","(Ljava/lang/String;)V",(void*)operateString},
{"operateIntArray","([II)[I",(void*)operateIntArray},
};
static const char*const kClassPathName ="com/xtmedia/xtsip/SipNative";
#define NELEM(x) ((int) (sizeof(x) /sizeof((x)[0])))
// This function only registers the native methods
static int register_android_xt_sip(JNIEnv *env)
{
return AndroidRuntime::registerNativeMethods(env,kClassPathName, gMethods, NELEM(gMethods));
}
jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
JNIEnv* env = NULL;
jint result = -1;
g_vm = vm;
if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
// ALOGE("ERROR: GetEnv failed\n");
goto bail;
}
// assert(env != NULL);
// g_vm = vm;
if (register_android_xt_sip(env) < 0) {
//ALOGE("ERROR: MediaPlayer native registration failed\n");
__android_log_print(ANDROID_LOG_ERROR, "JNI_OnLoad" ,"ERROR: MediaPlayer native registration failed\n");
goto bail;
}
__android_log_print(ANDROID_LOG_ERROR, "JNI_OnLoad" ,"success -- return valid version number\n");
/* success -- return valid version number */
result = JNI_VERSION_1_4;
bail:
return result;
}