最近有時間,研究了下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類,