Android Studio下的NDK开发(三):C中通过JNIEnv访问Java中的内容

1、编写java native类

直接上代码


public class JniUntil {
    public static int a=7;
    public static int b=8;

    public static int sum(int a,int b){
        return a+b;
    }

    public native int askByJni();

    static {
        System.loadLibrary("JniTest");
    }

}



2、生成通过terminal生成.class文件 


打开terminal如图

Android Studio下的NDK开发(三):C中通过JNIEnv访问Java中的内容



执行 
cd app/src/main/java/com/jnidemo_iii/
进入到JniUntil.java所在的目录

Android Studio下的NDK开发(三):C中通过JNIEnv访问Java中的内容


然后执行
javac JniUntil.java
可以看到目录里多了一个JniUntil.class的文件

Android Studio下的NDK开发(三):C中通过JNIEnv访问Java中的内容



3、通过terminal生成.h头文件



再执行
cd ..
cd ..
javah com.jnidemo_iii.JniUntil
生成.h文件,如图
Android Studio下的NDK开发(三):C中通过JNIEnv访问Java中的内容



4、配置CmakeList.txt



将.h头文件拷贝到cpp目录下,新建com_jnidemo_iii_JniUntil.c文件,在CmakeLis.txt文件中加入如下代码:
Android Studio下的NDK开发(三):C中通过JNIEnv访问Java中的内容




Android Studio下的NDK开发(三):C中通过JNIEnv访问Java中的内容




5、编写c文件




在com_jnidemo_iii_JniUntil.c中编写代码,如下

#include "com_jnidemo_iii_JniUntil.h"

JNIEXPORT jint JNICALL Java_com_jnidemo_1iii_JniUntil_askByJni
        (JNIEnv * env, jobject obj){
    //获取JniUntil实例
    jclass jniuntil=(*env)->GetObjectClass(env,obj);
    //获取a的id
    //第一个参数是环境,第二个参数是实例,第三个参数是变量名,第四个参数是签名
    jfieldID a_id=(*env)->GetStaticFieldID(env,jniuntil,"a","I");
    //通过a的id获取a的值
    jint a=(*env)->GetStaticIntField(env,jniuntil,a_id);
    //获取b的id
    jfieldID b_id=(*env)->GetStaticFieldID(env,jniuntil,"b","I");
    //通过b的id获取b的值
    jint b=(*env)->GetStaticIntField(env,jniuntil,b_id);
    //获取函数JniUntil.sum函数id
    //第一个参数是环境,第二个参数是实例,第三个参数是函数名,第四个参数是签名
    jmethodID id_sum=(*env)->GetStaticMethodID(env,jniuntil,"sum","(II)I");
    //调用sum函数
    //第一个参数是环境,第二个参数是实例,第三个参数是函数的id号,第四、五个参数是是sum()函数的参数
    int c=(*env)->CallStaticIntMethod(env,jniuntil,id_sum,a,b);
    //返回sum函数结果
    return c;
}


6、通过terminal获取签名

执行javap -s -p JniUntil.class
 descriptor:之后的就是签名

Android Studio下的NDK开发(三):C中通过JNIEnv访问Java中的内容



7、生成动态链接库




编译运行,生成库文件,其目录在如下图

Android Studio下的NDK开发(三):C中通过JNIEnv访问Java中的内容


拷贝到JnilIbs

Android Studio下的NDK开发(三):C中通过JNIEnv访问Java中的内容



8、编写mainActivity测试结果



编辑MainActivity中的代码,如下

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView result=(TextView)findViewById(R.id.result);
        JniUntil until=new JniUntil();
        int a=until.askByJni();
        Log.e("a","");
        result.setText(""+a);
    }
    
}


运行,结果如图

Android Studio下的NDK开发(三):C中通过JNIEnv访问Java中的内容



10、源码链接