JNI练习

MaiinActivity.java

package com.example.as_jni_project;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.TextView;

import com.example.as_jni_project.databinding.ActivityMainBinding;

public class MainActivity extends AppCompatActivity {

    // Used to load the 'as_jni_project' library on application startup.
    static {
        System.loadLibrary("as_jni_project");
    }

    private ActivityMainBinding binding;

    private String name = "Derry";//等下用c++代码,修改为Beyond
    public  static int age = 28;//等下用native代码 修改为:29
    private double number = 100000;
    private final double number = 900000;//用c++暴力修改 get是没有问题,set在之前版本有问题,现在也没有问题了

    /**
     * A native method that is implemented by the 'as_jni_project' native library,
     * which is packaged with this application.
     */
    public native String stringFromJNI();
    public native void changeName();//改变我们的属性name
    public static  native  void changeAge();//改变我们的属性age
    private  native  void changeNumber();
    public native void callAddMathod();//c调用java方法--->public int add(int number1, int number2){}

    //"(II)I"
    //被C调用的方法
    public int add(int number1, int number2){
        System.out.println("C居然调用了我");
        return number1+number2+90;
    }

    //(I)V
    public int add(int number1){
        return number1;
    }

    //(Ljava/lang/String;)Ljava/lang/String;
    //被C调用的方法
    public String shoew String(String str, int value){
        System.out.println("C居然调用了我 showString str:" + str + "vale:" + value);
        return"【" + str + "】";
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        // Example of a call to a native method
        TextView tv = binding.sampleText;
        tv.setText(stringFromJNI());

        System.out.println("name修改前是"+name);
        changeName();
        System.out.println("name修改后是"+name);

        System.out.println("age修改前是"+age);
        changeAge();
        System.out.println("age修改后是"+age);

        System.out.println("number修改前是"+number);
        changeNumber();
        System.out.println("number修改后是"+number);

        callAddMathod();
    }

}

native.cppp

#include <jni.h>
#include <string>

//日志输出
#include <android/log.h>
#define TAG "Derry"

//__VA_ARGS__ 代表 ...的可变参数
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__);
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__);
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__);

extern "C" JNIEXPORT jstring JNICALL
Java_com_example_as_1jni_1project_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

extern "C"//下面的代码,采用c的编译方式?为什么要这样,JNIEnv源码
JNIEXPORT//重要关键字,标记该方法可以被外界调用
void //代表java中的void
JNICALL//约束函数入栈顺序,和推栈内存清理的规则
//Java包名 com_xx_xx_1_类名_方法名
//JNIEnv *env JNI 桥梁 核心
//jobject == MainActivity this 实例调用的
//jclass == MainActivity class 类调用的
Java_com_derry_as_1jni_1project_MainActivity_changeName(JNIEnv *env, jobject mainActivitThis){
    //如果当前是native-lib.c
    //(*env)->xxx函数
    //(*env)->DeleteLocalRef()
    //C语言是JNIEnv *env 二级指针
    //(*env)->DeleteLocalRef(env, NULL);//c没有对象,想持有env环境,就必须传递进去

    //如果当前是native-lib.cpp
    //env->xxx函数
    //env->DeleteLocalRef()
    //C++语言是JNIEnv *env 一级指针
    //env->DeleteLocalRef(NULL);//C++有对象,本来就会持有this



    //String Student Person Object 引用类型  == JNI全部命名为Object

    jclass mainActivitCls = env->FindClass("Android/as_1jni_1project_1cpp/MainActivity");

    //jfieldID GetFieldID(jclass clazz, const char* name, const char* sig)
    jfieldID nameFid = env->GetFieldID(mainActivitCls, "name", "Ljava/lang/String;");//方式一

    //void SetObjectField(jobject obj, jfieldID jfieldID, jobject value)
    jstring value = env->NewStringUTF("修改为fff");
    env->SetObjectField(mainActivitThis,nameFid, value);
}

exctern "C"
JNIEXPORT void JNICALL
Java_com_derry_as_1jni_1project_1cpp_MainActivity_changeAge(JNIEnv *env, jclass mainActivityCls){

    //jclass mainActivityCls = env->GetObjectClass(mainActivityThis);//方式二

    //jfieldID GetStaticFieldID(jclass clazz, const char* name, const char* sig)
    jfieldID ageFid = env->GetStaticFieldID(mainActivityCls, "age", "I");

    //void SetIntField(jobject obj, jfieldID fieldID, jint value)
    env->SetStaticIntField(mainActivityCls, ageFid, 29);

    //jint 背后就是int, 可以直接用,string不行,必须用jstring
    //int age = env->GetStaticIntField(mainActivityCls, ageFid);//获取之前的age
    //env->SetStaticIntField(mainActivityCls, ageFid, age+10);
}

exctern "C"
JNIEXPORT void JNICALL
Java_com_derry_as_1jni_1project_1cpp_MainActivity_changeNumber(JNIEnv *env, jclass mainActivitThis){

    jclass mainActivityCls = env->GetObjectClass(mainActivitThis);

    //jfieldID GetStaticFieldID(jclass clazz, const char* name, const char* sig)
    jfieldID numberFid = env->GetFielID(mainActivityCls,"number","D");

    //void SetDoubleField(jobject obj, jfieldID fieldID, jint value)
    env->SetDoubleField(mainActivitThis, numberFid, 885.55);


    //修改 final number2======================

    jfieldID numberFid2 = env->GerFieldID(mainActivityCls,"number2", "D");

    env->SetDoubleField(mainActivitThis, numberFid2, 999999.9);

    double result = env->GetDoubleField(mainActivitThis, numberFid2);

    //__android_log_print(ANDROID_LOG_DEBUG, TAG,  __VA_ARGS__);
    LOGD("final result:%lf\n", result);
}

exctern "C"
JNIEXPORT void JNICALL
Java_com_derry_as_1jni_1project_1cpp_MainActivity_changeNumber(JNIEnv *env, jclass mainActivityThis){

    jclass mainActivitCls = env->GetObjectClass(mainActivitThis);

    //jmethodID(*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
    jmethodID addMid = env->GetMethodID(mainActiviCls, "add", "(II)I");

    //jint CallVoidMethod(jobject obj, jmethodID methodID, ...)
    int result = env->CallVoidMethod(mainActivitThis, addMid, 1, 1);
    LOGD("result:%d\n", result);


    //C调用public String shoew String(String str, int value)+++++++++++++++++++++++++++

    jmethodID showStringMid = env->GetMethodID(mainActivitCls, "showString", "(Ljava/lang/String;)Ljava/lang/String;");

    //jobject(*CallobjectMethod)(jobject, jmethodID, ...);
    jstring value = env->NewStringUFF("liyuanba");
    jstring resultStr = (jstring) env->CallObjectMethod(mainActivitThis, showStringMid, value, 9527);
    const char * resultCstr = env->GetDtringUTFChars(resultStr, NULL);
    LOGD("r==:%s\n", resultCstr);
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值