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如图
执行
cd app/src/main/java/com/jnidemo_iii/
进入到JniUntil.java所在的目录
然后执行
javac JniUntil.java
可以看到目录里多了一个JniUntil.class的文件
3、通过terminal生成.h头文件
再执行
cd ..
cd ..
javah com.jnidemo_iii.JniUntil
生成.h文件,如图
4、配置CmakeList.txt
将.h头文件拷贝到cpp目录下,新建com_jnidemo_iii_JniUntil.c文件,在CmakeLis.txt文件中加入如下代码:
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:之后的就是签名
7、生成动态链接库
编译运行,生成库文件,其目录在如下图
拷贝到JnilIbs
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); } }
运行,结果如图