最近有时间,研究了下android NDK 的使用方法,记录下,与大家一起分享;
android NDK环境配置就不介绍啦,网上太多。
下图是执行代码 后显示结果:
直接上代码,代码句句有描述;
MainActivity.java
public class MainActivity extends AppCompatActivity {
static {
System.loadLibrary("native-lib");
}
private String name;
private static int age = 10;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
changeName();
changeAge();
String uuid = uuid();
// Example of a call to a native method
TextView tv = (TextView) findViewById(R.id.sample_text);
tv.setText(stringFromJNI() + "\n name:" + name + "\n age:" + age + "\n uuid: " + uuid + "\n uuid2:" + staticUUID());
}
public String getUUID() {
return UUID.randomUUID().toString();
}
private static String getStaticUUID() {
return UUID.randomUUID().toString();
}
public native String stringFromJNI();
public native void changeName();
public native void changeAge();
public native String uuid();
private native String staticUUID();
}
如下是c文件的内容:
native-lib.cpp
#include <jni.h>
#include <string>
#include <android/log.h>
//返回一个jstring
extern "C"
JNIEXPORT jstring JNICALL
Java_com_bxn_ndkdemo_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
char hello[] = "Hello from C++";
return env->NewStringUTF(hello);
}
//改变java 非静态属性 name
extern "C"
JNIEXPORT void JNICALL
Java_com_bxn_ndkdemo_MainActivity_changeName(
JNIEnv *env,
jobject jobj) {
//通过jobj得到 jclass(MainActivity.class)
jclass clas = env->GetObjectClass(jobj);
//得到属性id
jfieldID fielId = env->GetFieldID(clas, "name", "Ljava/lang/String;");
//创建一个c中的字符串
char str[] = "hello ch";
//把c中的字符串,转成jni字符串
jstring jstr = env->NewStringUTF(str);
//设置 java中的属性
env->SetObjectField(jobj, fielId, jstr);
}
//改变java静态属性
extern "C"
JNIEXPORT void JNICALL
Java_com_bxn_ndkdemo_MainActivity_changeAge(
JNIEnv *env,
jobject jobj) {
//通过jobj得到 jclass(MainActivity.class)
jclass clas = env->GetObjectClass(jobj);
//得到静态属性id
jfieldID fielId = env->GetStaticFieldID(clas, "age", "I");
//得到静态属性的值
jint jint1 = env->GetStaticIntField(clas, fielId);
//自加1
jint1 += 1;
//设置 java静态属性
env->SetStaticIntField(clas, fielId, jint1);
}
//调用java非静态方法
extern "C"
JNIEXPORT jstring JNICALL
Java_com_bxn_ndkdemo_MainActivity_uuid(
JNIEnv *env,
jobject jobj) {
//通过jobj得到 jclass(MainActivity.class)
jclass clas = env->GetObjectClass(jobj);
//得到静态方法的id
jmethodID jmID = env->GetMethodID(clas, "getUUID", "()Ljava/lang/String;");
//调用java中的非静态方法
jstring jstr = (jstring) env->CallObjectMethod(jobj, jmID);
//将jni中的字符转成c中的字符
const char *uuid_str = env->GetStringUTFChars(jstr, NULL);
//这条命令是在LOGCAT中打印(可忽略)
__android_log_print(ANDROID_LOG_INFO, "JNITag", "%s", uuid_str);
return jstr;
}
//调用java静态方法
extern "C"
JNIEXPORT jstring JNICALL
Java_com_bxn_ndkdemo_MainActivity_staticUUID(
JNIEnv *env,
jobject jobj) {
//通过jobj得到 jclass(MainActivity.class)
jclass clas = env->GetObjectClass(jobj);
//得到java中的静态方法id
jmethodID jmID = env->GetStaticMethodID(clas, "getStaticUUID", "()Ljava/lang/String;");
//调用java中静态方法
jstring jstr = (jstring) env->CallStaticObjectMethod(clas, jmID);
//将jni中的字符转成c中的字符
const char *uuid_str = env->GetStringUTFChars(jstr, NULL);
//这条命令是在LOGCAT中打印(可忽略)
__android_log_print(ANDROID_LOG_INFO, "JNITag", "%s", uuid_str);
return jstr;
}
------------------------------------------------------------------------------------
里面有涉及到 java中 属性及方法的签名 如 String : ”Ljava/lang/String"
可通过 javap -s -p XXX (XXX为类名)
得到,如果本文介绍的为MainActivity类,