JNI 在Android中的详细用法(续集)
2016-10-20 16:41
369 查看
前面一篇文章没有吧jni的问题啰嗦完,所以,接着啰嗦……
上面提到c代码里获取java方法的参数里有 方法签名
下面讲下如何获取这个签名:
还是以前面的例子为基础打开studio下面的终端(Terminal),输入命令:
cd app\build\intermediates\classes\debug
命令好长记不住怎么办?每层目录只打前两个字母,按Tab键,你就看到效果了!
接着执行 javap命令:
javap -p -s com.game.my.jnigongcheng.MainActivity
参数-p -s 后面是要查看的类名全称。
结果如下:
其中,descriptor:后面就是方法签名了!
下面我们动手添加个方法:
后面增加个toast的重载方法,只是多个参数。
获取方法签名之前,一定要点下锤子。
得到的签名为:(Ljava/lang/String;)V
下面,改动下c代码,调用这个方法:
点下锤子,运行,看到结果了吧!
这是在声明native方法所在类的方法调用,那么问题来了,别的类的方法能调用么?
当然可以了,要不然,我也不会在这里啰嗦了.
下面,新建个java类:
很简单的一个类,里面只有一个方法.
下面,获取方法签名,注意分号((Ljava/lang/String;)Ljava/lang/String;),修改c代码:
可以看到,我们调用了Out的hello方法,生成一个字符串,然后又调用了MainActivity的toast方法
好了,现在总结下C语言调用java的方法:
1. 通过(*env)->FindClass方法找到class对象;
2.根据class对象找到他的方法;
3.利用对象执行方法,如果是本类,就是传入的jobject对象,如果是其他类,就需要(*env)->AllocObject方法生成这个对象;
上面提到c代码里获取java方法的参数里有 方法签名
下面讲下如何获取这个签名:
还是以前面的例子为基础打开studio下面的终端(Terminal),输入命令:
cd app\build\intermediates\classes\debug
命令好长记不住怎么办?每层目录只打前两个字母,按Tab键,你就看到效果了!
接着执行 javap命令:
javap -p -s com.game.my.jnigongcheng.MainActivity
参数-p -s 后面是要查看的类名全称。
结果如下:
Compiled from "MainActivity.java" public class com.game.my.jnigongcheng.MainActivity extends android.support.v7.app.AppCompatActivity { public com.game.my.jnigongcheng.MainActivity(); descriptor: ()V protected void onCreate(android.os.Bundle); descriptor: (Landroid/os/Bundle;)V public native void say(); descriptor: ()V public void toast(); descriptor: ()V static {}; descriptor: ()V }
其中,descriptor:后面就是方法签名了!
下面我们动手添加个方法:
import android.widget.Toast; public class MainActivity extends AppCompatActivity { static { System.loadLibrary("hello"); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); say(); } public native void say(); public void toast(){ Toast.makeText(this, "java from C", Toast.LENGTH_SHORT).show(); } public void toast(String str){ Toast.makeText(this, str, Toast.LENGTH_SHORT).show(); } }
后面增加个toast的重载方法,只是多个参数。
获取方法签名之前,一定要点下锤子。
得到的签名为:(Ljava/lang/String;)V
下面,改动下c代码,调用这个方法:
// // Created by my on 2016/10/20. // #include "com_game_my_jnigongcheng_MainActivity.h" JNIEXPORT void JNICALL Java_com_game_my_jnigongcheng_MainActivity_say (JNIEnv *env, jobject obj){ //先找到类 jclass jcla = (*env)->FindClass(env,"com/game/my/jnigongcheng/MainActivity"); if(jcla == 0){ //没找到类,直接返回 return; } //再找方法 注意:这里方法签名变了 jmethodID mid = (*env)->GetMethodID(env,jcla,"toast","(Ljava/lang/String;)V"); if(mid ==0){ //不解释 return; } //执行方法 这里传入了参数 (*env)->CallVoidMethod(env,obj,mid,(*env)->NewStringUTF(env,"这个吐司是C弹的!")); }
点下锤子,运行,看到结果了吧!
这是在声明native方法所在类的方法调用,那么问题来了,别的类的方法能调用么?
当然可以了,要不然,我也不会在这里啰嗦了.
下面,新建个java类:
package com.game.my.jnigongcheng; /** * Created by my on 2016/10/20. */ public class Out { public String hello(String name){ return "Hello!!"+name; } }
很简单的一个类,里面只有一个方法.
下面,获取方法签名,注意分号((Ljava/lang/String;)Ljava/lang/String;),修改c代码:
// // Created by my on 2016/10/20. // #include "com_game_my_jnigongcheng_MainActivity.h" JNIEXPORT void JNICALL Java_com_game_my_jnigongcheng_MainActivity_say (JNIEnv *env, jobject obj){ //先找到类 jclass jcla = (*env)->FindClass(env,"com/game/my/jnigongcheng/Out"); jclass jclas = (*env)->FindClass(env,"com/game/my/jnigongcheng/MainActivity"); if(jcla == 0){ //没找到类,直接返回 return; } //再找方法 jmethodID mid = (*env)->GetMethodID(env,jcla,"hello","(Ljava/lang/String;)Ljava/lang/String;"); jmethodID method = (*env)->GetMethodID(env,jclas,"toast","(Ljava/lang/String;)V"); if(mid == 0 || method == 0){ //不解释 return; } //生成对象 jobject jobj = (*env)->AllocObject(env,jcla); //执行方法 jstring jstr = (*env)->CallObjectMethod(env,jobj,mid,(*env)->NewStringUTF(env,"小明")); (*env)->CallVoidMethod(env,obj,method,jstr); }
可以看到,我们调用了Out的hello方法,生成一个字符串,然后又调用了MainActivity的toast方法
好了,现在总结下C语言调用java的方法:
1. 通过(*env)->FindClass方法找到class对象;
2.根据class对象找到他的方法;
3.利用对象执行方法,如果是本类,就是传入的jobject对象,如果是其他类,就需要(*env)->AllocObject方法生成这个对象;
相关文章推荐
- JNI 在Android中的详细用法
- JNI在android中的详细用法(再续)
- android的logcat详细用法
- android的logcat详细用法
- android的logcat详细用法
- android的logcat详细用法
- android的logcat详细用法
- android的logcat详细用法
- android的logcat详细用法
- (转)android的logcat详细用法
- android的logcat详细用法
- Android webservice的用法详细讲解
- android的logcat详细用法
- Android的JNI用法
- android的logcat详细用法
- Android------startActivityForResult的详细用法
- android的logcat详细用法
- android的logcat详细用法
- 通过Android平台移植魂斗罗游戏来阐述下jni的用法(把魂斗罗游戏嵌入到FC游戏模拟器里,省去了SD卡加载ROM)
- android的logcat详细用法zt