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