文章目录
1.概述
JAVA编程语言支持两种成员,每个实例都有自己的类成员拷贝,然而所有实例共享静态成员。 JNI提供一系列函数支持原生代码获取和设置实例成员和类静态成员。本篇我们来介绍下如何访问类静态成员。
2. 静态成员访问流程
3. java类静态成员JNI访问接口
3.1 类静态成员JNI读访问接口(GetStaticxxxField)
JNI对不同的类型提供了的访问接口
3.1 类静态成员JNI写访问接口(GetStaticxxxField)
4. 类静态成员访问测试
4.1 定义JNI类
我们先定义JNI的接口类,类定义有静态成员,代码如下:
package com.yangyongfeng.JNI_library;
public class StaticFieldAccess {
private boolean flag;
public static int sField = 100;
public static char my_sex = 'M';
public native void accessStaticField();
public static void setsField(int sField) {
StaticFieldAccess.sField = sField;
}
public static int getsField() {
return sField;
}
static {
System.loadLibrary("StaticFieldAccess");
}
}
4.2 定义JNI 库实现
我们在原生方法里修改类静态成员my_sex值,然后在java类型中打印出来。
//
// Created by Administrator on 2020/12/29 0029.
//
#include "static_field_access.h"
#include <jni.h>
#include <string.h>
#include <stdio.h>
JNIEXPORT void JNICALL Java_com_yangyongfeng_JNI_1library_StaticFieldAccess_accessStaticField(JNIEnv *env,jobject obj)
{
jfieldID fid;
jint si;
char type ;
//get reference to obj's class
jclass cls = (*env).GetObjectClass(obj);
if ( cls == NULL )
return;
printf("Run in C:\n");
//look for the static field si in cls
//fid = (*env).GetStaticFieldID(cls,"my_sex","C");
fid = (*env).GetStaticFieldID(cls,"my_sex","C");
if (fid == NULL){
return;
}
type = (*env).GetStaticCharField(cls,fid);
printf("StaticFieldIntField.type = %d\n",type);
(*env).SetStaticCharField(cls,fid,'F');
}
4.3 标题修改CMakeLists.txt
在CMakeLists.txt中增加编译配置,将原生方法static_field_access.cpp编译成动态库StaticFieldAccess.so,配置如下:
add_library( # Specifies the name of the library.
StaticFieldAccess
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
static_field_access.cpp )
4.4 测试demo
JNI原生库测试代码如下:
private void StaticFieldAccessTest(){
Log.d(TAG,this.toString());
StaticFieldAccess fieldAccess = new StaticFieldAccess();
Log.d(TAG,Integer.toString(StaticFieldAccess.my_sex));
Log.d(TAG,"FieldAccess addr:" + fieldAccess.toString());
fieldAccess.accessStaticField();
//StaticFieldAccess.accessStaticField();
Log.d(TAG,"New value: " + StaticFieldAccess.my_sex);
}
5. 遇到的问题
不能将原生方法定义为静态(static)方法,定义为静态方法后,通过 类名.原生静态方法 调用原生方法时,传递给JNI接口的对象错误,在查找类静态成员是会抛出NoSuchFieldError异常。
6 代码仓库
7. 我的公众号
关注我的公众号,分享嵌入式开发,android开发原创文章