android NDK 开发方式有很多种,随着android studio的崛起谷歌官方的开发方式是 cmake 形式的开发,在eclpse时代大多数使用的是android.mk等方式。今天主要使用cmake方式学习整个流程。
1.创建c/c++项目
在我们创建项目的时候我们可以勾选上support c/c++,这样我们创建的项目就有默认支持了cmake,
add_library( # Sets the name of the library.
native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
src/main/cpp/native-lib.cpp 此处可加入我们自己的cpp文件)
2.引入library包
// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("native-lib");
}
3.简单创建一个类
public class Helper {
//本地方法
public native String getJavaPackage(Context context);
//被c调用的方法
public String getPackage(Context context){
return context.getPackageName();
}
}
我们通过c来调用以下java方法并且把当前项目的包名返回
4.创建 public native String getJavaPackage(Context context);的 c 方法
extern "C"
JNIEXPORT jstring JNICALL
Java_com_example_ts_javatoc_Helper_getJavaPackage(JNIEnv *env, jobject instance, jobject context) {
return env->NewStringUTF(c_pm);
}
参数介绍:
JNIEnv *env : JNIEnv:在c中是结构体指针(方法中是二级指针),在c++中是结构体(方法中是一级指针)。且JNIEnv在整个内存中只有一个对象。
jobject instance : 指的是当前的native方法所在的类的对象
jobject context : 我们传的对象
5.调用流程
extern "C"
JNIEXPORT jstring JNICALL
Java_com_example_ts_javatoc_Helper_getJavaPackage(JNIEnv *env, jobject instance, jobject context) {
jclass jc = env->GetObjectClass(instance);
//这里主要是方法的签名,下面说以下怎么获取方法签名
jmethodID id = env->GetMethodID(jc,"getPackage","(Landroid/content/Context;)Ljava/lang/String;");
//注意我们掉的getPackage()方法是有参数的,所以我们在此处要把参数传进去
jstring pm = (jstring)env->CallObjectMethod(instance,id,context);
const char* c_pm = env->GetStringUTFChars(pm,0);
return env->NewStringUTF(c_pm);
}
6.获取方法签名
这种开发的知识点我在这篇文章中jni知识点总结 https://blog.csdn.net/WangRain1/article/details/94562527 中记录的有,这里再提一次:
获得java类中的方法/属性的签名
javap -s xxx.class
android studio需要 cd 到
build/intermediates/classes/…
or
build/intermediates/javac/debug/compileDebugJavaWithJavac/classes...
项目地址github:https://github.com/WangRain1/JavatoC