android java 与 native交互 基础学习(一)
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 的值:10
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;
}