android NDK 之C调java属性及方法

最近有时间,研究了下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类,



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值