Android的JNI技术

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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值