Android Studio下JNI环境搭建、编译、运行等可以参考:
http://blog.youkuaiyun.com/huangximin1990/article/details/50441400
上篇文章讲述的JNI示例程序主要涉及两个文件:
NativeKit.java
cn_com_losy_jnitest_jni_NativeKit.cpp
注:由于字体调整关系,下列所示代码多了很多<span></span>标签。需要源码的同学可直接到git下载
https://git.oschina.net/huangximin/JniTest-AS.git
NativeKit.java文件(各方法功能注释写得很清楚,不做赘述)
/**
* Created by huangximin on 2015/12/24.
* 说明:本类中以Java层为基本视角
* Java层向native层传参称为传入
* native层向Java层传参称为传出
*/
public class NativeKit {
private String name = "Java";
// 回调方法.native层的doCallback方法会调用本方法
public void callbackForJni(String fromNative) {
Log.d("jni", "jni string from native:" + fromNative);
}
// 加载so文件
static {
System.loadLibrary("JniDemo");
}
// 求平方.分别测试int/float/double/long的传入和传出
public native int square(int num);
public native float square(float num);
public native double square(double num);
public native long square(long num);
// 欢迎词.测试String的传入和传出
public native String greetings(String username);
// 获取二维数组.dimon*dimon的int型数组
public native int[][] getTwoArray(int dimon);
// 设置name.测试native层直接修改Java类成员变量
public native void nativeSetName();
// 回调.这个方法有点绕.native层的doCallback方法会再调用Java层(本类)的callbackForJni方法
public native void doCallback();
// 获取User实例.测试native层创建对象,然后返回给Java层
public native User nativeGetUser();
// native层获取Java层对象,并获取成员变量
public native void printUserInfoAtNative(User user);
// 修改User对象成员变量.同时测试Java层对象的传入、修改、传出
public native User changeUserInfo(User user);
// 获取对象列表.测试native层创建Java层对象列表,并返回
public native ArrayList<User> nativeGetUserList(int num);
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
cn_com_losy_jnitest_jni_NativeKit.cpp文件的内容比较多,按照NativeKit类中方法声明顺序逐个看。
<span style="font-size:18px;color:#ff0000;">public native int square(int num);</span>
方法对应以下述方法:
<span style="font-size:18px;">JNIEXPORT jint JNICALL Java_cn_com_losy_jnitest_jni_NativeKit_square__I
(JNIEnv * env, jobject obj, jint num) {
return num * num;
}</span>
其中,
JNIEXPORT 和JNICALL为JNI关键字,不用管它们
jint 对应int (具体数据类型对应详见本文最后)
Java_cn_com_losy_jnitest_jni_NativeKit_square__I 指明对应的方法
cn.com.losy.jnitest.jni包中的NativeKit类中的square方法
注:由于该类中square方法存在重载现象,而C语言没有重载,JNI的处理方法是在上述方法名最后面增加了
__I (后面的I表示参数为一个int
字样以区分不同的方法
JNIEnv * env JNIEnv 是JNI核心,有众多用处,后面会看到
jobject obj 这个jobject需要两种情况分析。上段代码中square