文章目录
1、新建Jni类
package com.luminal.ndktest;
/**
* 用来封装Jni的native接口的
*/
public class Jni {
//因为有很多地方要调用到,所以写成单例
private static Jni obj = new Jni();
public static Jni instance() {
return obj;
}
//加载动态库
static {
//动态库的名字,参见"CMakeLists.txt"文件
System.loadLibrary("native-lib");
}
//写一个native方法getStringFromJni,
//那么我们在c++代码里面要写一个对应的方法
public native String getStringFromJni();
}
动态库名字的来源
动态库的名字,参见"CMakeLists.txt"文件,如下图:
gradle简单介绍
当我们运行项目的时候,它有这个gradle会自动编译动态库。
gradle 类似于java编译脚本,编译的时候会根据配置文件进行编译,如:根据配置文件build.gradle(Module:app)
用C++来写NDK非常麻烦,如果你只改变C++的代码,不改变java的代码,它不会重新加载这个动态库!
非常的头痛,那么使用cmake之后,就不会出现这种问题,它会根据依赖关系自动编译代码。
2、native-lib.cpp的c++代码
#include <jni.h>
#include <string>
//************** 与java的Jni类中getStringFromJni方法所对应的方法 **************
//1、方法名的定义,前面已经介绍(上篇文章)。
//2、返回值类型
//getStringFromJni方法返回的是String类型,此c++方法对应返回的是jstring类型。
//jstring是c++中定义的类型,用来映射java类型,相当于java的String字符串类型。
//如:jobject相当于java的Object对象类型
//3、参数类型
//java中的getStringFromJni方法没有定义参数类型,
//但jni规范规定要多添加两个参数:JNIEnv* env, jobject obj
//env表示java虚拟机对象。因为java的代码是运行在虚拟机上的,所以env可以理解为java虚拟机。
//obj表示调用该方法的java对象。
//该方法指的是:Java_com_luminal_ndktest_Jni_stringFromJNI 方法
//这个java对象指的是Jni类对象,Jni类是一个单例对象,也就指的是定义的那个obj对象
//参见上面“1、新建Jni类”
//为什么需要 extern "C" ???
//它能够保证c++编译此方法的时候,不会对这个方法进行变名,
//如果没有的话,c++编译器会把此方法变名,那么变成别的名字java就找不到了
//所以使用 extern "C" ,来保证方法名不变,java虚拟机才能找到这个方法
extern "C" jstring Java_com_luminal_ndktest_Jni_getStringFromJni(JNIEnv* env, jobject obj){
return env->NewStringUTF("Test xxx");
}
3、MainActivity类
package com.luminal.ndktest;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
//动态库加载一次就行了,在Jni类里面已经加载!多次加载会出问题
// Used to load the 'native-lib' library on application startup.
// static {
// System.loadLibrary("native-lib");
// }
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Example of a call to a native method
// TextView tv = (TextView) findViewById(R.id.sample_text);
// tv.setText(stringFromJNI());
String str = Jni.instance().getStringFromJni();
TextView tv = (TextView) findViewById(R.id.sample_text);
tv.setText(str);
Log.v("MainActivityTag",str);
}
/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
// public native String stringFromJNI();
}
最终效果如下: