android NDK 之C调java属性及方法

最近有时间,研究了下android NDK 的使用方法,记录下,与大家一起分享;


android NDK环境配置就不介绍啦,网上太多。

下图是执行代码 后显示结果:

android NDK 之C调java属性及方法_第1张图片

直接上代码,代码句句有描述;

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 
#include 
#include 


//返回一个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类,


android NDK 之C调java属性及方法_第2张图片

你可能感兴趣的:(android)