接下来我们来看下Android怎么调用jni(Java Native Interface)
static {
System.loadLibrary("native-lib");
}
public native String stringsFromJNI();
public native String stringsFromJNI();
看这个书写方式是不是有点熟悉。跟java接口方法定义是不是也差不多啊,只不多了个native 修饰符。这样就代表是native层的东西。现在的Android studio编译器都会自己提示要让你在c里面生成对应的方法。如下
extern "C"
JNIEXPORT jstring JNICALL
Java_com_cpp_jni_MainActivity_stringsFromJNI(JNIEnv *env, jobject instance) {
jstring my_str=env->NewStringUTF("Hello JNI");
jint i=1;
LOGE("我的int值是%s",my_str);
const char* back=env->GetStringUTFChars(my_str, 0);
return env->NewStringUTF(back);
}
(注:这种注册方法我们成为静态注册)有静态肯定有动态,不过暂时不去了解.
我们来分下:
(1)、extern “C”
修饰的函数或者变量是按照C语言方式编译和链接的,所以可以用一句话来概括extern “C”的真实目的:实现C++与C的混合编程。你可以尝试删除试试会不会报错,✧(≖✿)嘿嘿。
(2)、JNIEXPORT jstring JNICALL
看名字就可以知道这是对应android端的返回值类型。
(3)、Java_com_cpp_jni_MainActivity_stringsFromJNI()
com_cpp_jni_MainActivity对应我的类的全路径
stringsFromJNI()对应的方法名
Java对应的是跟java进行交互固定写法。
(4)、(JNIEnv *env, jobject instance)
*env 指针在这里我们可以理解为上下文对象,即android中的Conrtext,这家伙牛逼哄哄的啊。
instance 这个是啥呢?其实这个就是指的 MainActivity对象(因为我的方法是从MainActivity里面声明的)
接下来我们随便在声明一个方法:
public static native void getDate(int a,Long b,short c,double d,byte e,String f,boolean g,MainActivity activity);看下生成的对应native
extern "C"
JNIEXPORT void JNICALL
Java_com_cpp_jni_MainActivity_getDate(JNIEnv *env, jclass type, jint a, jobject b, jshort c,
jdouble d, jbyte e, jstring f_, jboolean g,
jobject activity) {
const char *f = env->GetStringUTFChars(f_, 0);
//这是自动生成的哦,大家可以想想为何要release
env->ReleaseStringUTFChars(f_, f);
}
由于我们的方法是static类型的所以第二个参数变成了jclass。大家可以想想这是为啥?其实很简单。我们java中的调用一般有类调用和对象调用。jclass对应的就是类类型,jobject 对应的对象类型
其实方法调用这块很简单,重要的是我们要了解规则。
以上主要讲解的是Android调用native
下一篇我们分析native调用android。
虽然有的东西看着难,但是学到了你就会发现很简单。而且学习也是一件很有乐趣的事情。
希望有人跟我一起共勉,以上写的不对的地方请大家斧正。