Android中Jni的基本使用详解
来源:互联网 发布:白额高脚蛛淘宝 编辑:程序博客网 时间:2024/05/16 18:35
今天就介绍下jni编程的基本使用,如果你还不知道NDK的环境怎么搭建就看我的上一篇博客,有详细的介绍怎么搭建环境,生成So库的详细过程,上一篇博客的地址点击打开链接,下面介绍jni的基本使用:
在调用So库之前需要先加载So库
static { System.loadLibrary("JniTests");}静态代码块,先执行。
MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener { private TextView tv_call,call,call2; static { System.loadLibrary("JniTests"); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv_call=(TextView)findViewById(R.id.tv_call); call=(TextView)findViewById(R.id.call); call2=(TextView)findViewById(R.id.call2); tv_call.setOnClickListener(this); call.setOnClickListener(this); call2.setOnClickListener(this); } public native String javaCallC(); public native void javaC(); public native int callAdd(); public void cCallJava(String s){ Toast.makeText(MainActivity.this,s,Toast.LENGTH_SHORT).show(); } public int addInt(int x, int y){ Toast.makeText(MainActivity.this,"C调用了java的方法,x:"+x+"y:"+y),Toast.LENGTH_SHORT).show(); return x+y; } @Override public void onClick(View v) { switch (v.getId()){ case R.id.tv_call: String s=javaCallC(); Toast.makeText(MainActivity.this,s,Toast.LENGTH_SHORT).show(); break; case R.id.call: System.out.println("Java调用了C,C反调了java的方法"); javaC(); break; case R.id.call2: int add=callAdd(); System.out.println("Java调用了C,C反调了java的方法,求和为:"+add); break; } }}
JAVA调用C语言的是native方法
先说第一个方法:public native String javaCallC();
在C语言中对应的方法名就是Java_包名_类名_方法名,这个如果怕写错的话可以生成.h文件,从.h文件中直接copy出来C中对应的方法如下:
JNIEXPORT jstring JNICALL Java_com_wdkj_test_jniproject_MainActivity_javaCallC(JNIEnv *env, jobject object){ return (*env)->NewStringUTF(env, "JAVAcallC"); }javaCallC()返回的是String类型,在C中对应的是jstring,在点击第一个textview的时候调用了这个javaCallC()的方法,调用了C对应方法
Java_com_wdkj_test_jniproject_MainActivity_javaCallC,得到返回的字符串JAVAcallC,在手机端会弹出一个Toast提示“JAVAcallC”,效果如下:
第二个java调C的方法:public native void javaC(),也包含了C调Java的方法cCallJava(String s);
来C中对应的方法如下:
JNIEXPORT void JNICALL Java_com_wdkj_test_jniproject_MainActivity_javaC(JNIEnv *env, jobject jobject){ jclass clazz=(*env)->FindClass(env,"com/wdkj/test/jniproject/MainActivity"); jmethodID methodId=(*env)->GetMethodID(env,clazz,"cCallJava","(Ljava/lang/String;)V"); // jint (*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...); jstring str=(*env)->NewStringUTF(env,"hello 我调用了java的方法"); (*env)->CallVoidMethod(env,jobject,methodId,str); }C中对应的方法同样调用了java中的cCallJava方法,使用到了反射获取到MainActivity,根据方法名和参数得到方法ID,str是传参的变量值,cCallJava是void方法所以使用CallVoidMethod,CallVoidMethod传入了方法ID和变量值,调用了MainActivity的cCallJava方法。我点击第二个textview会调用javaC方法,C会执行Java_com_wdkj_test_jniproject_MainActivity_javaC,而Java_com_wdkj_test_jniproject_MainActivity_javaC方法中又使用反射调用了cCallJava方法,在手机端会弹出一个Toast提示“hello 我调用了java的方法”,效果如下:
第三个java调C的方法:public native int callAdd(),也包含了C调Java的方法addInt(int x,int y);
来C中对应的方法如下:
JNIEXPORT jint JNICALL Java_com_wdkj_test_jniproject_MainActivity_callAdd (JNIEnv *env, jobject jobject) { jclass clazz=(*env)->FindClass(env,"com/wdkj/test/jniproject/MainActivity"); //这里的方法签名中有几个I表示有几个参数 jmethodID methodId=(*env)->GetMethodID(env,clazz,"addInt","(II)I"); // jint 返回值是int(*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...); return (*env)->CallIntMethod(env,jobject,methodId,3,5);}java调C返回值是int所以C的返回值是jint,最后调用的是CallIntMethod,我点击第三个textview会调用callAdd方法,C会执行Java_com_wdkj_test_jniproject_MainActivity_callAdd,而Java_com_wdkj_test_jniproject_MainActivity_callAdd方法中又使用反射调用了addInt方法,在手机端会弹出一个Toast提示“C调用了java的方法,x:”+y:,展示C调addInt传的参数,java调C最后返回的一个int值,在控制台输出,效果如下:
希望对大家能有帮助,源码地址:点击打开链接,下载必须选C币我也没办法,有需要源码的可以留言,我直接发你们邮箱。
阅读全文
0 0
- Android中Jni的基本使用详解
- Android中JNI使用基本步骤
- android--jni--基本数据类型的使用
- Android JNI的基本使用(CMake)
- Android中JNI的使用
- Android中jNI的使用
- android中JNI的使用
- Android中JNI的使用
- Android中JNI的使用
- Android中JNI的使用
- Android中JNI的使用
- Android中JNI的使用
- Android中JNI的使用
- Android-JNI使用详解
- Android JNI 使用的数据结构JNINativeMethod详解 动态注册JNI
- Android JNI 使用的数据结构JNINativeMethod详解
- Android JNI 使用的数据结构JNINativeMethod详解
- Android JNI 使用的数据结构JNINativeMethod详解
- ESP-32 官方开发平台搭建过程小结
- coursera-斯坦福-机器学习-吴恩达-第1周笔记
- 为什么使用数据库从库
- [arc064f]Rotated Palindromes
- 九九乘法表
- Android中Jni的基本使用详解
- Android Window 机制探索
- 第十二周训练总结(一)
- 求100到300之间能被3整除的数的和
- 树的一些操作,杂记
- svn 客户端下载地址
- Python父目录、子目录相互调用
- easyui如何获取日期datebox中的值
- javac不是内部或外部命令,也不是可运行的程序或批处理文件