android jni基本使用方式

19 篇文章 0 订阅

JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++

一旦使用JNI,JAVA程序就丧失了JAVA平台的两个优点:1、程序不再跨平台。要想跨平台,必须在不同的系统环境下重新编译本地语言部分。2、程序不再是绝对安全的,本地代码的不当使用可能导致整个程序崩溃。一个通用规则是,你应该让本地方法集中在少数几个当中。这样就降低了JAVA和C之间的耦合性

为什么使用NDK

  1.代码的保护。由于apk的java层代码很容易被反编译,而C/C++库反汇难度较大。

  2.可以方便地使用现存的开源库。大部分现存的开源库都是用C/C++代码编写的。

  3.提高程序的执行效率。将要求高性能的应用逻辑使用C开发,从而提高应用程序的执行效率。

  4.便于移植。用C/C++写得库可以方便在其他的嵌入式平台上再次使用。



    //编译环境  Eclipse cywin ndk10
	//jni文档 http://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/jniTOC.html
	
	
	// src目录下运行  编译生成头文件
	// $ javah -d ../jni com.lmy.androidndksimple.MainActivity


	
	//方法签名 
	//javap -p -s -classpath bin/classes/ com.lmy.androidndksimple.MainActivity
	// Compiled from "Contact.java"
	// public class com.lmy.androidndksimple.Contact {
	// public com.lmy.androidndksimple.Contact(java.lang.String, int);
	// Signature: (Ljava/lang/String;I)V       //在GetMethodID(env, contactCls,"<init>","(Ljava/lang/String;I)V");中使用
	//
	// public java.lang.String getContactStr();
	// Signature: ()Ljava/lang/String;
	// }

源码路径

点击打开链接


该示例包含了jni常用的操作


//--------Exception----------------
	private native void ExceptionDemo();
	private native void FatalErrorDemo();//一般调试时使用
	
	
	
	
	//-----c调用java成员函数---------
	private native void AccessStaticMethodDemo(Dummy p);
	private native void AccessInstaceMethodDemo(Dummy p);
	
	
	//------c调用java数据成员------------
	private int intF;
	private String strF;
	private int[] intArrF;
	private Dummy dummyF;
	private static int sintF = 111;
	private static String sstrF = "static str";
	private static int[] sintArrF = {1,2,3};
	private static Dummy sdummyF = new Dummy(333);
	private native void AccessStaticFiledDemo();
	private native void AccessInstanceFiledDemo();
	
	
	
	//------------数组-------------
	private native void GetArrayLengthDemo(double[] p1,Dummy[] p2,int[][] p3);
	//此代码有问题,错误写法仅供参考
	private native void IllegalDirectAccessDemo(int[] p);
	private native Dummy[] NewObjectArrayDemo(Dummy p);
	private native int[] NewIntArrayDemo();
	private native Dummy GetSetObjectArrayDemo(Dummy[] p1,Dummy p2);
	private native void GetReleaseIntArrayDemo(int[] p);
	private native void GetSetIntArrayRegionDemo(int[] p1);
	
	
	//-----类实例------
	private native Contact GetObjectClassDemo(Contact p);
	private native void IsInstanceOfDemo();
	private native Contact AllocObjectDemo();
	private native Contact NewObjectDemo(String name,int age);
	private native Contact NewObjectADemo(String name,int age);
	private native Contact NewObjectVDemo(String name,int age);
	
	
	
	
	
	
	
	

	//-----类jclass-----
	private native void findClassDemo();
	private native void GetSuperClassDemo();
	//---继承关系判断--
	private native void IsAssignableFromDemo();
	
	
	
	//-----全局 弱引用  局部-----
	private native void referenceAssignmentAndNew(String p);

	private native void localReference(String p, boolean b);

	private native void globalReference(String p, boolean b);

	private native void weakReference(String p, boolean b);

	
	//----字符串处理  (java中编码为utf-16,android为utf-8),jni不能直接使用string----
	private native String passStringReturnString(String string);

	
	
	
	//--基本类型---
	private native int add(int a, int b);

	private native boolean passBooleanReturnBoolean(boolean b);

	private native byte passByteReturnByte(byte b);

	private native char passCharReturnChar(char c);

	private native short passShortReturnShort(short s);

	private native int passIntReturnInt(int i);

	private native long passLongReturnLong(long l);

	private native float passFloatReturnFloat(float f);

	private native double passDoubleReturnDouble(double d);


jni调用类 

public class Contact {

	
	private String name;
	private int age;
	public Contact(String name, int age) {
		this.name = name;
		this.age = age;
	}
	
	
	public void setName(String name)
	{
		this.name = name;
	}
	
	public String getContactStr()
	{
		return  name + ":" + age;
	}
	
}

public class Dummy {

	public static int staticValue = 100;
	private int value;
	public Dummy(int value) {
		this.value = value;
	}
	
	public Dummy() {
	}

	public static int getStaticValue() {
		return staticValue;
	}

	public static void setStaticValue(int staticValue) {
		Dummy.staticValue = staticValue;
	}

	public int getValue() {
		return value;
	}

	public void setValue(int value) {
		this.value = value;
	}

	public String getDummyValue()
	{
		return String.valueOf(value);
	}
}

package com.lmy.androidndksimple;

public class DummySubClass extends Dummy {

	private String name;
	
	public DummySubClass() {
	}
	
	public DummySubClass(int value,String name) {
		super(value);
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	
}

public interface DummyInterface {

}

public interface DummySubInterface extends DummyInterface{

}

mk文件

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := simple-ndk
LOCAL_SRC_FILES := main.c


#android log库
LOCAL_LDLIBS    := -llog

include $(BUILD_SHARED_LIBRARY)



具体实例MainActivity

package com.lmy.androidndksimple;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends Activity {

	//编译环境  Eclipse cywin ndk10
	//jni文档 http://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/jniTOC.html
	
	
	// src目录下运行  编译生成头文件
	// $ javah -d ../jni com.lmy.androidndksimple.MainActivity

	
	//方法签名    $ javap -s -classpath bin/classes/ com.lmy.androidndksimple.Contact
	//javap -p -s -classpath bin/classes/ com.lmy.androidndksimple.MainActivity
	// Compiled from "Contact.java"
	// public class com.lmy.androidndksimple.Contact {
	// public com.lmy.androidndksimple.Contact(java.lang.String, int);
	// Signature: (Ljava/lang/String;I)V       //在GetMethodID(env, contactCls,"<init>","(Ljava/lang/String;I)V");中使用
	//
	// public java.lang.String getContactStr();
	// Signature: ()Ljava/lang/String;
	// }

	static {
		System.loadLibrary("simple-ndk");
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		TextView textView = (TextView) findViewById(R.id.text);
		textView.setText("" + add(1, 2) + "-" + passBooleanReturnBoolean(false)
				+ "-" + passByteReturnByte((byte) 100) + "-"
				+ passCharReturnChar('a') + "-"
				+ passShortReturnShort((short) 100) + "-"
				+ passIntReturnInt(100) + "-" + passLongReturnLong(100) + "-"
				+ passFloatReturnFloat(100f) + "-"
				+ passDoubleReturnDouble(100) + "-"
				+ passStringReturnString("cg") + "-"
				+ passStringReturnString(null));
		
		
		localReference("hello local ref", true);
		//localReference false可能引起程序崩溃,内存不够
		//localReference("hello local ref", false);
		
		globalReference("hello glocal ref", false);
		globalReference("hello glocal ref2", true);
		globalReference("hello glocal ref3", true);
		
		weakReference("hello weak ref", false);
		weakReference("hello weak ref2", true);
		weakReference("hello weak ref3", true);
		
		referenceAssignmentAndNew("hello ndk");
//		referenceAssignmentAndNew("");
		
		findClassDemo();
		GetSuperClassDemo();
		IsAssignableFromDemo();
	
		
		
		callAllocNewDemo();
		callGetObjectDemo();
		callsInstaceDemo();
		
		calllegalDirectAccessDemo();
		callGetArrayLengthDemo();
		
		callNewObjectArrayDemo();
		callNewIntArrayDemo();
		
		
		
		callGetSetObjectArrayDemo();
		callGetReleaseIntArrayDemo();
		callGetSetIntArrayRegionDemo();
		
		callAccessInstanceFiledDemo();
		callAccessStaticFiledDemo();
		
		
		callAccessInstaceMethodDemo();
		callAccessStaticMethodDemo();
		
		callExceptionDemo();
		callFatalErrorDemo();
		
	}


	private void callAllocNewDemo()
	{
		Contact con1 = AllocObjectDemo();
		Contact con2 = NewObjectADemo("B", 20);
		Contact con3 = NewObjectADemo("C", 30);
		Contact con4 = NewObjectADemo("D", 40);
		StringBuffer stringBuffer = new StringBuffer();
		stringBuffer.append(con1.getContactStr()).append("啪啪啪\n");
		stringBuffer.append(con2.getContactStr()).append("啪啪啪\n");
		stringBuffer.append(con3.getContactStr()).append("啪啪啪\n");
		stringBuffer.append(con4.getContactStr()).append("啪啪啪\n");
		System.out.println(stringBuffer);
	}
	
	
	
	private void callGetObjectDemo()
	{
		Contact con5 = GetObjectClassDemo(new Contact("dummy", 100));
		StringBuffer stringBuffer = new StringBuffer();
		stringBuffer.append(con5.getContactStr()).append("啪啪啪");
		System.out.println(stringBuffer);
	}
	
	
	
	private void callsInstaceDemo()
	{
		IsInstanceOfDemo();
	}
	
	
	
	private void callNewObjectArrayDemo()
	{
		Dummy dummy = new Dummy(5);
		Dummy[] dummyArr = NewObjectArrayDemo(dummy);
		System.out.println("NewObjectArrayDemo size :" + dummyArr.length);
	}
	
	private void callNewIntArrayDemo()
	{
		int[] results = NewIntArrayDemo();
		System.out.println("NewIntArrayDemo int[] size :" + results.length + "-" + results[results.length-1]);
	}
	
	
	
	private void callGetArrayLengthDemo()
	{
		double[] dArr = new double[10];
		Dummy[] dummyArr = new Dummy[20];
		int[][] intarr = new int[30][40];
		GetArrayLengthDemo(dArr, dummyArr, intarr);
	}
	
	
	
	
	private void calllegalDirectAccessDemo()
	{
		int arr[] = new int[10];
		for(int i=0;i<10;i++)
		{
			arr[i] = i;
		}
		IllegalDirectAccessDemo(arr);
	}
	
	
	private void callGetSetObjectArrayDemo()
	{
		Dummy[] dummies = new Dummy[3];
		for(int i=0;i<3;i++)
		{
			dummies[i] = new Dummy(i);
		}
		Dummy dummy = GetSetObjectArrayDemo(dummies, new Dummy(100));
		System.out.println("GetSetObjectArrayDemo info :" + dummy.getDummyValue());
	}
	
	private void callGetReleaseIntArrayDemo()
	{
		int[] intArr = new int[5];
		for(int i=0;i<5;i++)
		{
			intArr[i] = i;
		}
		GetReleaseIntArrayDemo(intArr);
		System.out.println("GetReleaseIntArrayDemo intArr[2]:" + intArr[2] );
	}
	
	
	private void callGetSetIntArrayRegionDemo()
	{
		int[] intArr = new int[5];
		for(int i=0;i<5;i++)
		{
			intArr[i] = i;
		}
		GetSetIntArrayRegionDemo(intArr);
		System.out.println("GetSetIntArrayRegionDemo intArr[0]:" + intArr[0] );
	}
	
	
	private void callAccessStaticFiledDemo()
	{
		AccessStaticFiledDemo();
		System.out.println("AccessStaticFiledDemo :" + sintF + "-" + sstrF + "-"+ sdummyF.getDummyValue() + "-" + sintArrF[0]);
	}
	
	
	private void callAccessInstanceFiledDemo()
	{
		intF = 222;
		strF = "instanceStr";
		intArrF = new int[]{1,2,3,4,5};
		dummyF = new Dummy(666);
		AccessInstanceFiledDemo();
		System.out.println("AccessInstanceFiledDemo :" + intF + "-" + strF + "-"+ dummyF.getDummyValue() + "-" + intArrF[0]);
	}
	
	
	private void callAccessStaticMethodDemo()
	{
		Dummy dummy = new Dummy(1);
		Dummy.setStaticValue(200);
		AccessStaticMethodDemo(dummy);
		System.out.println("AccessStaticMethodDemo staticvalue :" + Dummy.getStaticValue());
		
	}
	
	private void callAccessInstaceMethodDemo()
	{
		DummySubClass dummy = new DummySubClass(1,"A");
		AccessInstaceMethodDemo(dummy);
		System.out.println("AccessInstaceMethodDemo name value :" + dummy.getName());
		
	}
	
	private void callExceptionDemo()
	{
		try {
			ExceptionDemo();
		} catch (RuntimeException e) {
			System.out.println("runtime error deal");
		}
	}
	

	private void callFatalErrorDemo()
	{
		//FatalErrorDemo();
		System.out.println("致命错误");
	}

	
	
	
	//--------Exception----------------
	private native void ExceptionDemo();
	private native void FatalErrorDemo();//一般调试时使用
	
	
	
	
	//-----c调用java成员函数---------
	private native void AccessStaticMethodDemo(Dummy p);
	private native void AccessInstaceMethodDemo(Dummy p);
	
	
	//------c调用java数据成员------------
	private int intF;
	private String strF;
	private int[] intArrF;
	private Dummy dummyF;
	private static int sintF = 111;
	private static String sstrF = "static str";
	private static int[] sintArrF = {1,2,3};
	private static Dummy sdummyF = new Dummy(333);
	private native void AccessStaticFiledDemo();
	private native void AccessInstanceFiledDemo();
	
	
	
	//------------数组-------------
	private native void GetArrayLengthDemo(double[] p1,Dummy[] p2,int[][] p3);
	//此代码有问题,错误写法仅供参考
	private native void IllegalDirectAccessDemo(int[] p);
	private native Dummy[] NewObjectArrayDemo(Dummy p);
	private native int[] NewIntArrayDemo();
	private native Dummy GetSetObjectArrayDemo(Dummy[] p1,Dummy p2);
	private native void GetReleaseIntArrayDemo(int[] p);
	private native void GetSetIntArrayRegionDemo(int[] p1);
	
	
	//-----类实例------
	private native Contact GetObjectClassDemo(Contact p);
	private native void IsInstanceOfDemo();
	private native Contact AllocObjectDemo();
	private native Contact NewObjectDemo(String name,int age);
	private native Contact NewObjectADemo(String name,int age);
	private native Contact NewObjectVDemo(String name,int age);
	
	
	
	
	
	
	
	

	//-----类jclass-----
	private native void findClassDemo();
	private native void GetSuperClassDemo();
	//---继承关系判断--
	private native void IsAssignableFromDemo();
	
	
	
	//-----全局 弱引用  局部-----
	private native void referenceAssignmentAndNew(String p);

	private native void localReference(String p, boolean b);

	private native void globalReference(String p, boolean b);

	private native void weakReference(String p, boolean b);

	
	//----字符串处理  (java中编码为utf-16,android为utf-8),jni不能直接使用string----
	private native String passStringReturnString(String string);

	
	
	
	//--基本类型---
	private native int add(int a, int b);

	private native boolean passBooleanReturnBoolean(boolean b);

	private native byte passByteReturnByte(byte b);

	private native char passCharReturnChar(char c);

	private native short passShortReturnShort(short s);

	private native int passIntReturnInt(int i);

	private native long passLongReturnLong(long l);

	private native float passFloatReturnFloat(float f);

	private native double passDoubleReturnDouble(double d);
}


c实现

#include "com_lmy_androidndksimple_MainActivity.h"
#include <android/log.h>
#include <jni.h>
#include <string.h>
#define LOG_TAG "hello-ndk"

#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))





/*
 * Class:     com_lmy_androidndksimple_MainActivity
 * Method:    ExceptionDemo
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_lmy_androidndksimple_MainActivity_ExceptionDemo
  (JNIEnv *env, jobject pObj){
	    jboolean ifExceptionPending = (*env)->ExceptionCheck(env);
		LOGI("ExceptionCheck : %d",ifExceptionPending);
		jthrowable exception = (*env)->ExceptionOccurred(env);
		LOGI("ExceptionOcurred resulted NULL? : %d",(*env)->IsSameObject(env,exception,NULL));

		//search for a class which are not available,which will cause an exception
		(*env)->FindClass(env,"java/lang/XXYY");
		//use ExceptionCheck to check
		ifExceptionPending = (*env)->ExceptionCheck(env);
		LOGI("ExceptionCheck after finding non-existing class : %d",ifExceptionPending);
		(*env)->ExceptionClear(env);//clear the exception,so we can proceed
	    ifExceptionPending = (*env)->ExceptionCheck(env);
		LOGI("ExceptionCheck  after clear : %d",ifExceptionPending);


		//throw a java.lang.NULLPointerException using thrownew
		jclass cls = (*env)->FindClass(env,"java/lang/NullPointerException");
		jint st = (*env)->ThrowNew(env,cls,"throw null pointer exception");
		if(st==0)
		{
			LOGI("null pointer exception throw using thrownew");
			(*env)->DeleteLocalRef(env,cls);
		}

		//using exceptionOcurred to check
		jthrowable exObj = (*env)->ExceptionOccurred(env);
		if(exObj == NULL)
		{
			LOGI("No Exception");
		}else
		{
			LOGI("there's pending exception,call ExceptionDescribe");
			(*env)->ExceptionDescribe(env);//this does not clear the exception
			ifExceptionPending = (*env)->ExceptionCheck(env);
			LOGI("ExceptionCheck after ExceptionDescribe : %d",ifExceptionPending);
			(*env)->ExceptionClear(env);clear the exception,so we can proceed
			ifExceptionPending = (*env)->ExceptionCheck(env);
			LOGI("ExceptionCheck  after clear : %d",ifExceptionPending);
			(*env)->DeleteLocalRef(env,exObj);
		}

		//throw a runtimeexception using throw
		cls = (*env)->FindClass(env,"java/lang/RuntimeException");
		jmethodID exConstructor = (*env)->GetMethodID(env,cls,"<init>","(Ljava/lang/String;)V");

		jstring msg = (*env)->NewStringUTF(env,"throw runtime exception");
		exObj = (*env)->NewObject(env,cls,exConstructor,msg);
		(*env)->DeleteLocalRef(env,msg);
		if(exObj==NULL)
		{
			LOGI("cretate tuntimeException failed");
		}else
		{
			jint st = (*env)->Throw(env,exObj);
			if(st==0)
			{
				LOGI("exception thrown using throw");
				(*env)->DeleteLocalRef(env,cls);
				(*env)->DeleteLocalRef(env,exObj);
			}
		}
}

/*
 * Class:     com_lmy_androidndksimple_MainActivity
 * Method:    FatalErrorDemo
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_lmy_androidndksimple_MainActivity_FatalErrorDemo
  (JNIEnv *env, jobject pObj){
	(*env)->FatalError(env,"fatal error");
	LOGI("after calling fatal error");
}













/*
 * Class:     com_lmy_androidndksimple_MainActivity
 * Method:    AccessStaticMethodDemo
 * Signature: (Lcom/lmy/androidndksimple/Dummy;)V
 */
JNIEXPORT void JNICALL Java_com_lmy_androidndksimple_MainActivity_AccessStaticMethodDemo
  (JNIEnv *env, jobject pObj, jobject pDummy){
	jmethodID  sGetValueMID,sSetValueMID;
	jclass dummyCls = (*env)->GetObjectClass(env,pDummy);

	sGetValueMID = (*env)->GetStaticMethodID(env,dummyCls,"getStaticValue","()I");
	sSetValueMID = (*env)->GetStaticMethodID(env,dummyCls,"setStaticValue","(I)V");

	//call the get method
	jint staticValue = (*env)->CallStaticIntMethod(env,dummyCls,sGetValueMID);
	LOGI("static value : %d",staticValue);
	//call set the method
	(*env)->CallStaticVoidMethod(env,dummyCls,sSetValueMID,123);
	//call get method again
	staticValue = (*env)->CallStaticIntMethod(env,dummyCls,sGetValueMID);
	LOGI("static value : %d",staticValue);

	//call the set method A
	jvalue args[1];
	args[0].i = 124;
	(*env)->CallStaticVoidMethodA(env,dummyCls,sSetValueMID,args);
	//call get method again
	staticValue = (*env)->CallStaticIntMethod(env,dummyCls,sGetValueMID);
	LOGI("static value : %d",staticValue);

	//call the set method V
	callStaticVoidMethodVUtil(env,dummyCls,sSetValueMID,125);
	//call get method again
	staticValue = (*env)->CallStaticIntMethod(env,dummyCls,sGetValueMID);
	LOGI("static value : %d",staticValue);

}

 void callStaticVoidMethodVUtil(JNIEnv *env,jobject pDummySub,jmethodID mid, ...){
	va_list arList;
	va_start(arList,mid);
	(*env)->CallStaticVoidMethodV(env,pDummySub,mid,arList);
	va_end(arList);
}




/*
 * Class:     com_lmy_androidndksimple_MainActivity
 * Method:    AccessInstaceMethodDemo
 * Signature: (Lcom/lmy/androidndksimple/Dummy;)V
 */
JNIEXPORT void JNICALL Java_com_lmy_androidndksimple_MainActivity_AccessInstaceMethodDemo
  (JNIEnv *env, jobject pObj, jobject pDummySub){
	jmethodID sGetNameMID,sSetNameMID;
	jclass dummySubCls = (*env)->GetObjectClass(env,pDummySub);
	sGetNameMID = (*env)->GetMethodID(env,dummySubCls,"getName","()Ljava/lang/String;");
	sSetNameMID = (*env)->GetMethodID(env,dummySubCls,"setName","(Ljava/lang/String;)V");
	//call the getMethod
	jstring name = (*env)->CallObjectMethod(env,pDummySub,sGetNameMID);
	const jbyte* nameStr = (*env)->GetStringUTFChars(env,name,NULL);
	LOGI("AccessInstaceMethodDemo name : %s",nameStr);
	(*env)->ReleaseStringUTFChars(env,name,nameStr);
	//call the setMethod
	jstring newNameStr = (*env)->NewStringUTF(env,"B");
	(*env)->CallVoidMethod(env,pDummySub,sSetNameMID,newNameStr);

	//Call the get method again
	name = (*env)->CallObjectMethod(env,pDummySub,sGetNameMID);
	nameStr = (*env)->GetStringUTFChars(env,name,NULL);
	LOGI("AccessInstaceMethodDemo name : %s",nameStr);
	(*env)->ReleaseStringUTFChars(env,name,nameStr);

	//call the set method A
	jvalue arg[1];
	arg[0].l = (*env)->NewStringUTF(env,"C");
	(*env)->CallVoidMethodA(env,pDummySub,sSetNameMID,arg);
	//Call the get method again
	name = (*env)->CallObjectMethod(env,pDummySub,sGetNameMID);
	nameStr = (*env)->GetStringUTFChars(env,name,NULL);
	LOGI("AccessInstaceMethodDemo name : %s",nameStr);
	(*env)->ReleaseStringUTFChars(env,name,nameStr);


	//call the set method V
	newNameStr = (*env)->NewStringUTF(env,"D");
	callVoidMethodVUtil(env,pDummySub,sSetNameMID,newNameStr);
	//Call the get method again
	name = (*env)->CallObjectMethod(env,pDummySub,sGetNameMID);
	nameStr = (*env)->GetStringUTFChars(env,name,NULL);
	LOGI("AccessInstaceMethodDemo name : %s",nameStr);
	(*env)->ReleaseStringUTFChars(env,name,nameStr);


	//子类调用父类的方法
	jmethodID sGetValueMID,sSetValueMID;
	jclass dummyCls = (*env)->GetSuperclass(env,dummySubCls);
	sGetValueMID = (*env)->GetMethodID(env,dummyCls,"getValue","()I");
	sSetValueMID = (*env)->GetMethodID(env,dummyCls,"setValue","(I)V");
	//call the nonvirtual get method
	jint value = (*env)->CallNonvirtualIntMethod(env,pDummySub,dummyCls,sGetValueMID);
	LOGI("AccessInstaceMethodDemo value : %d",value);
	//call the nonvirtual set method
	(*env)->CallNonvirtualVoidMethod(env,pDummySub,dummyCls,sSetValueMID,123);
	value = (*env)->CallNonvirtualIntMethod(env,pDummySub,dummyCls,sGetValueMID);
	LOGI("AccessInstaceMethodDemo value : %d",value);


}

 void callVoidMethodVUtil(JNIEnv *env,jobject pDummySub,jmethodID mid, ...){
	va_list arList;
	va_start(arList,mid);
	(*env)->CallVoidMethodV(env,pDummySub,mid,arList);
	va_end(arList);
}



/*
 * Class:     com_lmy_androidndksimple_MainActivity
 * Method:    AccessStaticFiledDemo
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_lmy_androidndksimple_MainActivity_AccessStaticFiledDemo
  (JNIEnv *env, jobject pObj){
	jfieldID sintFID,sstrFID,sintArrFID,sdummyFID;
	jclass cls = (*env)->GetObjectClass(env,pObj);

	sintFID = (*env)->GetStaticFieldID(env,cls,"sintF","I");
	//get field value
	jint sint = (*env)->GetStaticIntField(env,cls,sintFID);
	//set new int value
	(*env)->SetStaticIntField(env,cls,sintFID,123);

	sstrFID = (*env)->GetStaticFieldID(env,cls,"sstrF","Ljava/lang/String;");
	jobject sstr = (*env)->GetStaticObjectField(env,cls,sstrFID);
	const char* str = (*env)->GetStringUTFChars(env,sstr,NULL);
	if(str ==NULL)
	{
		LOGI("AccessStaticFiledDemo sstrF get Failed");
	}
	(*env)->ReleaseStringUTFChars(env,sstr,str);
	//set new String value
	jstring newStr = (*env)->NewStringUTF(env,"filed xxoo");
	(*env)->SetStaticObjectField(env,cls,sstrFID,newStr);


	sintArrFID = (*env)->GetStaticFieldID(env,cls,"sintArrF","[I");
	//get the in array field and  each element
	jobject sintarr = (*env)->GetStaticObjectField(env,cls,sintArrFID);
	jint *intArr = (*env)->GetIntArrayElements(env,sintarr,NULL);
	int i;
	jsize len = (*env)->GetArrayLength(env,sintarr);
	//intArr[i]
	(*env)->ReleaseIntArrayElements(env,sintarr,intArr,0);
	//set int arr field to a newly created array
	jintArray newIntArr = (*env)->NewIntArray(env,len);
	jint *newIntArrNative = (*env)->GetIntArrayElements(env,newIntArr,NULL);
	for(i=0;i<len;i++)
	{
		newIntArrNative[i] = 10*i;
	}
	(*env)->ReleaseIntArrayElements(env,newIntArr,newIntArrNative,0);
	(*env)->SetStaticObjectField(env,cls,sintArrFID,newIntArr);

	sdummyFID = (*env)->GetStaticFieldID(env,cls,"sdummyF","Lcom/lmy/androidndksimple/Dummy;");
	//get the sdummy field
	jobject sdummy = (*env)->GetStaticObjectField(env,cls,sdummyFID);
	jclass dummyCls = (*env)->FindClass(env,"com/lmy/androidndksimple/Dummy");
	LOGI("AccessStaticFiledDemo dummy is instance of dummyCls :%d",(*env)->IsInstanceOf(env,sdummy,dummyCls));
	jfieldID dummyValueFID = (*env)->GetFieldID(env,dummyCls,"value","I");
	jint dummyValue = (*env)->GetIntField(env,sdummy,dummyValueFID);
	LOGI("AccessStaticFiledDemo dummy value :%d",dummyValue);
	//set dummy field to a newly created one
	jmethodID dummyConstructor = (*env)->GetMethodID(env,dummyCls,"<init>","(I)V");
	jobject newDummy = (*env)->NewObject(env,dummyCls,dummyConstructor,100);
	(*env)->SetStaticObjectField(env,cls,sdummyFID,newDummy);

}

/*
 * Class:     com_lmy_androidndksimple_MainActivity
 * Method:    AccessInstanceFiledDemo
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_lmy_androidndksimple_MainActivity_AccessInstanceFiledDemo
  (JNIEnv *env, jobject pObj){
	jfieldID intFID,strFID,intArrFID,dummyFID;
	jclass cls = (*env)->GetObjectClass(env,pObj);

	intFID = (*env)->GetFieldID(env,cls,"intF","I");
	//get the int field
	jint aint = (*env)->GetIntField(env,pObj,intFID);
	LOGI("AccessInstanceFiledDemo intF:%d", aint);
	//set the int field
	(*env)->SetIntField(env,pObj,intFID,123);
	strFID = (*env)->GetFieldID(env,cls,"strF","Ljava/lang/String;");
	//get string field and read the content
	jobject astr = (*env)->GetObjectField(env,pObj,strFID);
	const char* str = (*env)->GetStringUTFChars(env,astr,NULL);
	if(str==NULL)
	{
		LOGI("AccessInstanceFiledDemo strF get Failed");
	}
	LOGI("AccessInstanceFiledDemo strF :%s",str);
	(*env)->ReleaseStringUTFChars(env,astr,str);
	//set the string field to a new string
	jstring newStr = (*env)->NewStringUTF(env,"xxoo");
	(*env)->SetObjectField(env,pObj,strFID,newStr);

	intArrFID = (*env)->GetFieldID(env,cls,"intArrF","[I");
	//get the int array and read the content
	jobject intarr = (*env)->GetObjectField(env,pObj,intArrFID);
	jint *intArr = (*env)->GetIntArrayElements(env,intarr,NULL);
	int i;
	jsize len = (*env)->GetArrayLength(env,intarr);
	for(i=0;i<len;i++)
	{
		LOGI("AccessInstanceFiledDemo region int[] :%d",intArr[i]);
	}
	(*env)->ReleaseIntArrayElements(env,intarr,intArr,0);
	//set the int array to a newly created array
	jintArray newIntArr = (*env)->NewIntArray(env,len);
	jint *newIntArrayNative = (*env)->GetIntArrayElements(env,newIntArr,NULL);
	for(i=0;i<len;i++)
	{
		newIntArrayNative[i] = i*10;
	}
	(*env)->ReleaseIntArrayElements(env,newIntArr,newIntArrayNative,0);
	(*env)->SetObjectField(env,pObj,intArrFID,newIntArr);
	dummyFID = (*env)->GetFieldID(env,cls,"dummyF","Lcom/lmy/androidndksimple/Dummy;");
	//get the dummy object field
	jobject adummy = (*env)->GetObjectField(env,pObj,dummyFID);
	jclass dummyCls = (*env)->FindClass(env,"com/lmy/androidndksimple/Dummy");
	LOGI("AccessInstanceFiledDemo dummy is instance of dummyCls :%d",(*env)->IsInstanceOf(env,adummy,dummyCls));
	jfieldID dummyValueFID = (*env)->GetFieldID(env,dummyCls,"value","I");
	jint dummyValue = (*env)->GetIntField(env,adummy,dummyValueFID);
	LOGI("AccessInstanceFiledDemo dummy value :%d",dummyValue);
	//set the dummy obj field to a newly created one
	jmethodID dummyConstructor = (*env)->GetMethodID(env,dummyCls,"<init>","(I)V");
	jobject newDummy = (*env)->NewObject(env,dummyCls,dummyConstructor,200);
	(*env)->SetObjectField(env,pObj,dummyFID,newDummy);
}













/*
 * Class:     com_lmy_androidndksimple_MainActivity
 * Method:    GetSetObjectArrayDemo
 * Signature: ([Lcom/lmy/androidndksimple/Dummy;Lcom/lmy/androidndksimple/Dummy;)Lcom/lmy/androidndksimple/Dummy;
 */
JNIEXPORT jobject JNICALL Java_com_lmy_androidndksimple_MainActivity_GetSetObjectArrayDemo
  (JNIEnv *env, jobject pObj, jobjectArray pArray, jobject pDummy){
	jobject dummy1 = (*env)->GetObjectArrayElement(env,pArray,1);
	(*env)->SetObjectArrayElement(env,pArray,1,pDummy);
	//dummy1 = (*env)->GetObjectArrayElement(env,pArray,1);
	return dummy1;
}

/*
 * Class:     com_lmy_androidndksimple_MainActivity
 * Method:    GetReleaseIntArrayDemo
 * Signature: ([I)V
 */
JNIEXPORT void JNICALL Java_com_lmy_androidndksimple_MainActivity_GetReleaseIntArrayDemo
  (JNIEnv *env, jobject pObj, jintArray pIntArr){
	jboolean isCopy;
	jint *intArr = (*env)->GetIntArrayElements(env,pIntArr,&isCopy);
	int i;
	jsize len = (*env)->GetArrayLength(env,pIntArr);
	for(i=0;i<len;i++)
	{
		intArr[i] *= 10;
	}
	(*env)->ReleaseIntArrayElements(env,pIntArr,intArr,0);
}

/*
 * Class:     com_lmy_androidndksimple_MainActivity
 * Method:    GetSetIntArrayRegionDemo
 * Signature: ([I)V
 */
JNIEXPORT void JNICALL Java_com_lmy_androidndksimple_MainActivity_GetSetIntArrayRegionDemo
  (JNIEnv *env, jobject pObj, jintArray pIntArr){
	int buff[16];
	(*env)->GetIntArrayRegion(env,pIntArr,1,3,buff);
	int i;
	for(i=0;i<3;i++)
	{
		buff[i] *=10;
	}
	(*env)->SetIntArrayRegion(env,pIntArr,0,3,buff);
}





/*
 * Class:     com_lmy_androidndksimple_MainActivity
 * Method:    NewObjectArrayDemo
 * Signature: (Lcom/lmy/androidndksimple/Dummy;)[Lcom/lmy/androidndksimple/Dummy;
 */
JNIEXPORT jobjectArray JNICALL Java_com_lmy_androidndksimple_MainActivity_NewObjectArrayDemo
  (JNIEnv *env, jobject pObj, jobject pDummyInit){
	jclass cls = (*env)->FindClass(env,"com/lmy/androidndksimple/Dummy");
	jarray objArr = (*env)->NewObjectArray(env,10,cls,pDummyInit);
	return objArr;
}

/*
 * Class:     com_lmy_androidndksimple_MainActivity
 * Method:    NewIntArrayDemo
 * Signature: ()[I
 */
JNIEXPORT jintArray JNICALL Java_com_lmy_androidndksimple_MainActivity_NewIntArrayDemo
  (JNIEnv *env, jobject pObj){
	jintArray jintArr = (*env)->NewIntArray(env,10);
	jboolean isCopy;
	jint *intArr = (*env)->GetIntArrayElements(env,jintArr,&isCopy);
	int i;
	for(i=0;i<10;i++)
	{
		intArr[i] = i;
	}
	(*env)->ReleaseIntArrayElements(env,jintArr,intArr,0);
	return jintArr;
}






/*
 * Class:     com_lmy_androidndksimple_MainActivity
 * Method:    GetArrayLengthDemo
 * Signature: ([D[Lcom/lmy/androidndksimple/Dummy;[[I)V
 */
JNIEXPORT void JNICALL Java_com_lmy_androidndksimple_MainActivity_GetArrayLengthDemo
  (JNIEnv *env, jobject pObj, jdoubleArray pDoubles, jobjectArray pObjs, jobjectArray pIInts){
	jsize len = (*env)->GetArrayLength(env,pDoubles);
	LOGI("size of Double[] :%d", len);
	len = (*env)->GetArrayLength(env,pObjs);
	LOGI("size of Dummy[] :%d", len);
	len = (*env)->GetArrayLength(env,pIInts);
	LOGI("size of int[][] :%d", len);
}


/*
 * Class:     com_lmy_androidndksimple_MainActivity
 * Method:    IllegalDirectAccessDemo
 * Signature: ([I)V
 */
JNIEXPORT void JNICALL Java_com_lmy_androidndksimple_MainActivity_IllegalDirectAccessDemo
  (JNIEnv *env, jobject pObj, jintArray pInts){
	jsize len = (*env)->GetArrayLength(env,pInts);
	int i;
	int *ints = (int*)pInts;
	for(i=0;i<len;i++)
	{
		//错误
		//LOGI("int array :%d",ints[i]);
	}
}












/*
 * Class:     com_lmy_androidndksimple_MainActivity
 * Method:    GetObjectClassDemo
 * Signature: (Lcom/lmy/androidndksimple/Contact;)Lcom/lmy/androidndksimple/Contact;
 */
JNIEXPORT jobject JNICALL Java_com_lmy_androidndksimple_MainActivity_GetObjectClassDemo
  (JNIEnv *env, jobject pObj, jobject pContact){
	jclass cls = (*env)->GetObjectClass(env,pContact);
	jmethodID method = (*env)->GetMethodID(env, cls,"<init>","(Ljava/lang/String;I)V");
	jobject allocObj = (*env)->AllocObject(env,cls);
	return allocObj;

}

/*
 * Class:     com_lmy_androidndksimple_MainActivity
 * Method:    IsInstanceOfDemo
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_lmy_androidndksimple_MainActivity_IsInstanceOfDemo
  (JNIEnv *env, jobject pObj){
	jclass dummyCls = (*env)->FindClass(env,"com/lmy/androidndksimple/Dummy");
	jclass dummySubCls = (*env)->FindClass(env,"com/lmy/androidndksimple/DummySubClass");
	jmethodID  dummyConstructor = (*env)->GetMethodID(env,dummyCls,"<init>","()V");
	jmethodID  dummySubConstructor = (*env)->GetMethodID(env,dummySubCls,"<init>","()V");
	jobject dummyObj = (*env)->NewObject(env,dummyCls,dummyConstructor);
	jobject dummySubObj = (*env)->NewObject(env,dummySubCls,dummySubConstructor);
	LOGI("dummyObj, dummyCls: %d",(*env)->IsInstanceOf(env,dummyObj,dummyCls));
	LOGI("dummyObj, dummySubCls: %d",(*env)->IsInstanceOf(env,dummyObj,dummySubCls));
	LOGI("dummySubObj, dummyCls: %d",(*env)->IsInstanceOf(env,dummySubObj,dummyCls));
	LOGI("dummySubObj, dummySubCls: %d",(*env)->IsInstanceOf(env,dummySubObj,dummySubCls));
}

/*
 * Class:     com_lmy_androidndksimple_MainActivity
 * Method:    AllocObjectDemo
 * Signature: ()Lcom/lmy/androidndksimple/Contact;
 */
JNIEXPORT jobject JNICALL Java_com_lmy_androidndksimple_MainActivity_AllocObjectDemo
  (JNIEnv *env, jobject pObj){
	jclass contactCls = (*env)->FindClass(env,"com/lmy/androidndksimple/Contact");
	jobject allocObj = (*env)->AllocObject(env,contactCls);
	LOGI("11111111111111111111111");
	jmethodID method = (*env)->GetMethodID(env, contactCls,"setName","(Ljava/lang/String;)V");
	LOGI("22222222222222222");
	if(method !=NULL)
	{

		(*env)->CallVoidMethod(env,allocObj, method, (*env)->NewStringUTF(env,"haha"));
		LOGI("55555555555555");
	}

	return allocObj;
}

/*
 * Class:     com_lmy_androidndksimple_MainActivity
 * Method:    NewObjectDemo
 * Signature: (Ljava/lang/String;I)Lcom/lmy/androidndksimple/Contact;
 */
JNIEXPORT jobject JNICALL Java_com_lmy_androidndksimple_MainActivity_NewObjectDemo
  (JNIEnv *env, jobject pObj, jstring pName, jint pAge){
	jclass contactCls = (*env)->FindClass(env,"com/lmy/androidndksimple/Contact");
	jmethodID method = (*env)->GetMethodID(env, contactCls,"<init>","(Ljava/lang/String;I)V");
	jobject newObj = (*env)->NewObject(env,contactCls,method,pName,pAge);
	return newObj;
}

/*
 * Class:     com_lmy_androidndksimple_MainActivity
 * Method:    NewObjectADemo
 * Signature: (Ljava/lang/String;I)Lcom/lmy/androidndksimple/Contact;
 */
JNIEXPORT jobject JNICALL Java_com_lmy_androidndksimple_MainActivity_NewObjectADemo
  (JNIEnv *env, jobject pObj, jstring pName, jint pAge){
	jclass contactCls = (*env)->FindClass(env,"com/lmy/androidndksimple/Contact");
	jmethodID method = (*env)->GetMethodID(env, contactCls,"<init>","(Ljava/lang/String;I)V");
	jvalue args[2];
//	typedef union jvalue {
//	    jboolean z;
//	    jbyte    b;
//	    jchar    c;
//	    jshort   s;
//	    jint     i;
//	    jlong    j;
//	    jfloat   f;
//	    jdouble  d;
//	    jobject  l;
//	} jvalue;
//
	args[0].l = pName;
	args[1].i = pAge;
	jobject newObject = (*env)->NewObjectA(env,contactCls,method,args);
	return newObject;
}


static jobject newObjectVUtil(JNIEnv *env, ...){
	jclass contactCls = (*env)->FindClass(env,"com/lmy/androidndksimple/Contact");
	jmethodID method = (*env)->GetMethodID(env, contactCls,"<init>","(Ljava/lang/String;I)V");
	va_list arList;
	va_start(arList,env);
	jobject newObjV = (*env)->NewObjectV(env,contactCls,method,arList);
	va_end(arList);
	return newObjV;
}


/*
 * Class:     com_lmy_androidndksimple_MainActivity
 * Method:    NewObjectVDemo
 * Signature: (Ljava/lang/String;I)Lcom/lmy/androidndksimple/Contact;
 */
JNIEXPORT jobject JNICALL Java_com_lmy_androidndksimple_MainActivity_NewObjectVDemo
  (JNIEnv *env, jobject p, jstring pName, jint pAge){
	return newObjectVUtil(env,pName,pAge);
}







/*
 * Class:     com_lmy_androidndksimple_MainActivity
 * Method:    findClassDemo
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_lmy_androidndksimple_MainActivity_findClassDemo
  (JNIEnv *env, jobject o){
	jclass strClass = (*env)->FindClass(env,"java/lang/String");
	if(strClass == NULL)
	{
		LOGI("find string class failed");
	}else
	{
		LOGI("find string class succeed");
		(*env)->DeleteLocalRef(env,strClass);
	}

	jclass dummyClass = (*env)->FindClass(env,"com/lmy/androidndksimple/Dummy");
	if(dummyClass ==NULL)
	{
		LOGI("find dummyClass class failed");
	}else
	{
		LOGI("find dummyClass class succeed");
		(*env)->DeleteLocalRef(env,dummyClass);
	}


}

/*
 * Class:     com_lmy_androidndksimple_MainActivity
 * Method:    GetSuperClassDemo
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_lmy_androidndksimple_MainActivity_GetSuperClassDemo
  (JNIEnv *env, jobject o){
	jclass objectClass = (*env)->FindClass(env,"java/lang/Object");
	jclass dummySubInterface = (*env)->FindClass(env,"com/lmy/androidndksimple/DummySubInterface");
	jclass dummySubClass = (*env)->FindClass(env,"com/lmy/androidndksimple/DummySubClass");

	jclass superOfObject = (*env)->GetSuperclass(env,objectClass);
	jclass superOfDummySubInterface = (*env)->GetSuperclass(env,dummySubInterface);
	jclass superOfDummySubClass = (*env)->GetSuperclass(env,dummySubClass);

	if(superOfObject == NULL)
	{
		LOGI("super object is null");
	}else
	{
		LOGI("super object is not null");
		nativeGetClassName(env,superOfObject);
	}

	if(superOfDummySubInterface == NULL)
	{
		LOGI("superOfDummySubInterface is null");
	}else
	{
		LOGI("superOfDummySubInterface is not null");
		nativeGetClassName(env,superOfDummySubInterface);
	}
	if(superOfDummySubClass == NULL)
	{
		LOGI("superOfDummySubClass is null");
	}else
	{
		LOGI("superOfDummySubClass is not null");
		nativeGetClassName(env,superOfDummySubClass);
	}

}


 void nativeGetClassName(JNIEnv *env, jclass pClass)
{
	 jmethodID midGetName = (*env)->GetMethodID(env,pClass,"toString","()Ljava/lang/String;");
	 if(midGetName !=NULL)
	 {
		 jstring jclassName = (jstring)(*env)->CallObjectMethod(env,pClass,midGetName);
		 if(jclassName!=NULL)
		 {
			 const char* className = (*env)->GetStringUTFChars(env,jclassName,NULL);
			 LOGI("nativeGetName_%s",className);
			 (*env)->ReleaseStringUTFChars(env,jclassName,className);
			 (*env)->DeleteLocalRef(env,jclassName);
		 }
	 }
}

/*
 * Class:     com_lmy_androidndksimple_MainActivity
 * Method:    IsAssignableFromDemo
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_lmy_androidndksimple_MainActivity_IsAssignableFromDemo
  (JNIEnv *env, jobject o){
	jclass dummySubClass = (*env)->FindClass(env,"com/lmy/androidndksimple/DummySubClass");
	jclass superOfDummySubClass = (*env)->GetSuperclass(env,dummySubClass);
	LOGI("From sub to super: %d",
			(*env)->IsAssignableFrom(env,dummySubClass,superOfDummySubClass));
	LOGI("From super to sub: %d",
				(*env)->IsAssignableFrom(env, superOfDummySubClass,dummySubClass));

}





/*
 * Class:     com_lmy_androidndksimple_MainActivity
 * Method:    referenceAssignmentAndNew
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_com_lmy_androidndksimple_MainActivity_referenceAssignmentAndNew
(JNIEnv *env, jobject o, jstring p){
	jstring globalRefNew = (*env)->NewGlobalRef(env,p);
	jstring globalRefNew2 = (*env)->NewGlobalRef(env,p);
	jstring globalRefAssignment = globalRefNew;
    //JNI_FALSE 0   TRUE 1
	LOGI("p and globalRefNew :%d", (*env)->IsSameObject(env,p,globalRefNew));
	LOGI("globalRefNew and globalRefNew2 :%d", (*env)->IsSameObject(env,globalRefNew,globalRefNew2));
	LOGI("globalRefNew and globalRefAssignment :%d", (*env)->IsSameObject(env,globalRefNew,globalRefAssignment));

	LOGI("pointer size : %u", sizeof(void*));
	LOGI("p : %u", p);
	LOGI("globalRefNew : %u", globalRefNew);
	LOGI("globalRefNew2 : %u", globalRefNew2);
	LOGI("globalRefAssignment : %u", globalRefAssignment);

	LOGI("call deleteGlobalRef globalRefNew");
	(*env)->DeleteGlobalRef(env,globalRefNew);
	LOGI("call deleteGlobalRef globalRefNew2");
	(*env)->DeleteGlobalRef(env,globalRefNew2);
//	LOGI("call deleteGlobalRef globalRefNew");
//	(*env)->DeleteGlobalRef(env,globalRefNew);
}

/*
 * Class:     com_lmy_androidndksimple_MainActivity
 * Method:    localReference
 * Signature: (Ljava/lang/String;Z)V
 */
JNIEXPORT void JNICALL Java_com_lmy_androidndksimple_MainActivity_localReference
(JNIEnv *env, jobject o, jstring p, jboolean b){
	jstring stStr;
	int i;
	LOGI("localReference_delete after allocation%d", b);
	for(i=0;i<10000;i++)
	{
		stStr = (*env)->NewLocalRef(env,p);
		if(b)
		{
			//不调用可能引起程序崩溃,内存不够
			(*env)->DeleteLocalRef(env,stStr);
		}
	}

}

/*
 * Class:     com_lmy_androidndksimple_MainActivity
 * Method:    globalReference
 * Signature: (Ljava/lang/String;Z)V
 */
JNIEXPORT void JNICALL Java_com_lmy_androidndksimple_MainActivity_globalReference
(JNIEnv *env, jobject o, jstring p, jboolean b){
	//全局只有一份
	static jstring stStr;
	const jbyte *str;
	jboolean *isCopy;
	if(stStr==NULL)
	{
		LOGI("globalReference_create global ref");
		stStr = (*env)->NewGlobalRef(env,p);
		if(NULL ==stStr)
		{
			LOGI("globalReference_cannot create global ref");
			return;
		}
	}
	str = (*env)->GetStringUTFChars(env,stStr,isCopy);
	if(NULL==str)
	{
		LOGI("globalReference_cannot convert jstring to utf-8 string");
		return;
	}
	LOGI("globalReference_print utf-8 string %s",str);
	(*(env))->ReleaseStringUTFChars(env,stStr,str);
	if(b)
	{
		(*env)->DeleteGlobalRef(env,stStr);
		stStr=NULL;
		LOGI("globalReference_global ref deleted");
	}

}

/*
 * Class:     com_lmy_androidndksimple_MainActivity
 * Method:    weakReference
 * Signature: (Ljava/lang/String;Z)V
 */
JNIEXPORT void JNICALL Java_com_lmy_androidndksimple_MainActivity_weakReference
(JNIEnv *env, jobject o, jstring p, jboolean b){

		static jstring stStr;
		const jbyte *str;
		jboolean *isCopy;
		if(stStr==NULL)
		{
			LOGI("weakReference_create weak ref");
			stStr = (*env)->NewWeakGlobalRef(env,p);
			if(NULL ==stStr)
			{
				LOGI("weakReference_cannot create weak ref");
				return;
			}
		}
		str = (*env)->GetStringUTFChars(env,stStr,isCopy);
		if(NULL==str)
		{
			LOGI("weakReference_cannot convert jstring to utf-8 string");
			return;
		}
		LOGI("weakReference_print utf-8 string %s",str);
		(*(env))->ReleaseStringUTFChars(env,stStr,str);
		if(b)
		{
			(*env)->DeleteWeakGlobalRef(env,stStr);
			stStr=NULL;
			LOGI("weakReference_weak ref deleted");
		}

}

/*
 * Class:     com_lmy_androidndksimple_MainActivity
 * Method:    passStringReturnString
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_lmy_androidndksimple_MainActivity_passStringReturnString(
		JNIEnv *env, jobject obj, jstring pStr) {
	//string (java中编码为utf-16,android为utf-8),不能直接使用string
	if (pStr == NULL) {
		//project 编码格式必须为utf-8
		const char* newStr = "hello 安卓";
		jstring ret = (*env)->NewStringUTF(env, newStr);
		return ret;
	}
	const jbyte *str;
	jboolean *isCopy;
	str = ((*env)->GetStringUTFChars(env, pStr, isCopy));

	if (str == NULL) {
		const char* newStr = "hello 安卓";
		jstring ret = (*env)->NewStringUTF(env, newStr);
		return ret;
	}
	jsize length = (*env)->GetStringUTFLength(env, pStr);
	(*env)->ReleaseStringUTFChars(env, pStr, str);
	char nativeStr[100] = { 0 };
	(*env)->GetStringUTFRegion(env, pStr, 0, length, nativeStr);
	const char* newStr = "成功返回";
	jstring ret = (*env)->NewStringUTF(env, newStr);
	//jsize newStrLen = (*env)->GetStringUTFLength(env,ret);
	return ret;
}

JNIEXPORT jint JNICALL Java_com_lmy_androidndksimple_MainActivity_add(
		JNIEnv *env, jobject object, jint a, jint b) {

	//__android_log_print(ANDROID_LOG_INFO, "hello-ndk", "a=%d,b=%d",a,b);
	LOGI("result=%d", a+b);
	return a + b;
}

/*
 * Class:     com_lmy_androidndksimple_MainActivity
 * Method:    passBooleanReturnBoolean
 * Signature: (Z)Z
 */
JNIEXPORT jboolean JNICALL Java_com_lmy_androidndksimple_MainActivity_passBooleanReturnBoolean(
		JNIEnv *env, jobject object, jboolean b) {
	return (!b);
}

/*
 * Class:     com_lmy_androidndksimple_MainActivity
 * Method:    passByteReturnByte
 * Signature: (B)B
 */
JNIEXPORT jbyte JNICALL Java_com_lmy_androidndksimple_MainActivity_passByteReturnByte(
		JNIEnv *env, jobject object, jbyte b) {
	return b + 1;
}

/*
 * Class:     com_lmy_androidndksimple_MainActivity
 * Method:    passCharReturnChar
 * Signature: (C)C
 */
JNIEXPORT jchar JNICALL Java_com_lmy_androidndksimple_MainActivity_passCharReturnChar(
		JNIEnv *env, jobject object, jchar c) {
	c = '*';
	return c;
}

/*
 * Class:     com_lmy_androidndksimple_MainActivity
 * Method:    passShortReturnShort
 * Signature: (S)S
 */
JNIEXPORT jshort JNICALL Java_com_lmy_androidndksimple_MainActivity_passShortReturnShort(
		JNIEnv *env, jobject object, jshort s) {
	return s + 2;
}

/*
 * Class:     com_lmy_androidndksimple_MainActivity
 * Method:    passIntReturnInt
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_com_lmy_androidndksimple_MainActivity_passIntReturnInt(
		JNIEnv *env, jobject object, jint i) {
	return i * 10;

}

/*
 * Class:     com_lmy_androidndksimple_MainActivity
 * Method:    passLongReturnLong
 * Signature: (J)J
 */
JNIEXPORT jlong JNICALL Java_com_lmy_androidndksimple_MainActivity_passLongReturnLong(
		JNIEnv *env, jobject object, jlong l) {
	return l + 100;
}

/*
 * Class:     com_lmy_androidndksimple_MainActivity
 * Method:    passFloatReturnFloat
 * Signature: (F)F
 */
JNIEXPORT jfloat JNICALL Java_com_lmy_androidndksimple_MainActivity_passFloatReturnFloat(
		JNIEnv *env, jobject object, jfloat f) {
	return f + 100;
}

/*
 * Class:     com_lmy_androidndksimple_MainActivity
 * Method:    passDoubleReturnDouble
 * Signature: (D)D
 */
JNIEXPORT jdouble JNICALL Java_com_lmy_androidndksimple_MainActivity_passDoubleReturnDouble(
		JNIEnv *env, jobject object, jdouble d) {
	return d + 100;
}






  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值