android java 與 native互動 基礎學習(一)
阿新 • • 發佈:2018-12-21
javap 與javah的用法
- javap 的用法: cd 到 class 所在的目錄: javap -classpath . -s Bean(類名)
- java h的用法一: native 所在的資料夾。ExampleUnitTest 資料夾所在的包 java.tanghuijuan.com.myjnitestone 1.cd 到java 目錄: 使用 javah -o ExampleUnitTest.h tanghuijuan.com.myjnitestone.ExampleUnitTest 則在 ExampleUnitTest的同級目錄下生成了 ExampleUnitTest.h 標頭檔案
NDK操作
new出來的物件一定要記得delete 所有的jobject 型別值也要記得 Release 指標 也要釋放
public class Bean { private String name; private int[] intArray; public static void staticMethod(int i, int b) { Log.i("tag", (i + b) + ""); } public Bean(String name, int[] intArray) { this.name = name; this.intArray = intArray; } public Bean() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public int[] getIntArray() { return intArray; } public void setIntArray(int[] intArray) { this.intArray = intArray; } }
native 方法
#include <jni.h> #include <string> #include <android/log.h> //定義一個巨集 列印 __VA_ARGS__ 的作用:獲取去可變引數...的值 __android_log_print 是android/log.h 下的方法 #define LOGE(...)__android_log_print(ANDROID_LOG_ERROR,"testBeanTag",__VA_ARGS__); extern "C" JNIEXPORT void JNICALL Java_com_tang_myndktesttwo_MainActivity_testBean(JNIEnv *env, jobject instance) { //找到Bean 型別, "/"相當於"." 用完之後記得釋放 jclass jclass1 = env->FindClass("com/tang/myndktesttwo/Bean"); //獲取去 static 方法 jmethodID staticMethod = env->GetStaticMethodID(jclass1, "staticMethod", "(II)V"); env->CallStaticVoidMethod(jclass1, staticMethod, 1, 1); //獲取構造方法 並且呼叫 用完之後記得釋放helper jmethodID constructMethod = env->GetMethodID(jclass1, "<init>", "()V"); jobject helper = env->NewObject(jclass1, constructMethod); // 呼叫 set方法 New出來的jstring記得釋放 jmethodID setNameMethond = env->GetMethodID(jclass1, "setName", "(Ljava/lang/String;)V"); jstring instanceStr = env->NewStringUTF("My Name is Tang"); env->CallObjectMethod(helper, setNameMethond, instanceStr); //呼叫get方法 返回 String 用完之後記得釋放 jstring 與cha* jmethodID getNameMethond = env->GetMethodID(jclass1, "getName", "()Ljava/lang/String;"); jstring str = static_cast<jstring>(env->CallObjectMethod(helper, getNameMethond)); const char *mychar = env->GetStringUTFChars(str, 0); env->ReleaseStringUTFChars(str, mychar); LOGE("getName 的值 %s", mychar); env->DeleteLocalRef(jclass1); env->DeleteLocalRef(instanceStr); env->DeleteLocalRef(helper); }
屬性的反射
int a = 10;
static String b = "java字串";
private static final String TAG = "MainActivity";
public native void reflectField();
extern "C"
JNIEXPORT void JNICALL
Java_com_tang_myndktesttwo_MainActivity_reflectField(JNIEnv *env, jobject instance) {
//instance 就是MainActivity 記得釋放jclass
jclass clazz = env->GetObjectClass(instance);
// jclass ,屬性名, 簽名
jfieldID a = env->GetFieldID(clazz, "a", "I");
int avalue = env->GetIntField(instance, a);
LOGE("int a 的值:%d", avalue);
//給屬性設定值
env->SetIntField(instance, a, 100);
jfieldID b = env->GetFieldID(clazz, "a", "I");
int bvalue = env->GetIntField(instance, b);
LOGE("int b 的值:%d", bvalue);
//獲取static String型別值
jfieldID staicField = env->GetStaticFieldID(clazz, "b", "Ljava/lang/String;");
jstring staicFieldStr = static_cast<jstring>(env->GetStaticObjectField(clazz, staicField));
const char *str = env->GetStringUTFChars(staicFieldStr, 0);
LOGE("int 的值:%s", str);
//釋放
env->ReleaseStringUTFChars(staicFieldStr, str);
env->DeleteLocalRef(clazz);
}
//結果
11-13 14:58:21.767 4034-4034/com.tang.myndktesttwo E/testBeanTag: int a 的值:100
11-13 14:58:21.767 4034-4034/com.tang.myndktesttwo E/testBeanTag: int b 的值:100
11-13 14:58:21.767 4034-4034/com.tang.myndktesttwo E/testBeanTag: int 的值:java字串
native 方法 動態註冊
// MainActivity java
static {
System.loadLibrary("native-lib");
}
public native void testBean();
public native void reflectField();
//c++ native-lib.cpp
void reflectField(JNIEnv *env, jobject instance) {
}
void testBean(JNIEnv *env, jobject instance) {
}
static const char *mClassname = "com/tang/myndktesttwo/MainActivity";
static const JNINativeMethod method[] = {
{"testBean", "()V", (void *) testBean},
{"reflectField", "()V", (void *) reflectField}
};
jint JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv *env = NULL;
int r = vm->GetEnv((void **) &env, JNI_VERSION_1_4);
if (r != JNI_OK) {
return -1;
}
jclass mainActivityCls = env->FindClass(mClassname);
r = env->RegisterNatives(mainActivityCls, method, 2);
if (r != JNI_OK) {
return -1;
}
// 2、4、6都可以
return JNI_VERSION_1_4;
}