1. 程式人生 > >android java 與 native互動 基礎學習(一)

android java 與 native互動 基礎學習(一)

javap 與javah的用法

  1. javap 的用法: cd 到 class 所在的目錄: javap -classpath . -s Bean(類名)
  2. 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;
}