[TOC]
# 1. 前言
在C中可以通过反射的方式来调用Java的代码,同样还是借助前面配置的JNI环境。这里首先配置要需要供C语言调用的Java类和方法:
~~~
public class JavaMethod {
public int add(int a, int b){
System.out.println("调用了JavaMethod类中的类方法。");
return a + b;
}
public static void showInfo(){
System.out.println("调用了JavaMethod类中的静态方法。");
}
}
~~~
# 2. 得到方法签名
可以使用javap命令来查看每个方法的签名,比如可以任意打开一个cmd窗口,执行:
```
javap -s java.lang.String
```
来查看String类中每个方法的签名。类似的,我们可以先编译一下这个项目,然后在build->intermediates->javac->debug->classes->com.xxx的字节码文件下:
![](https://img.kancloud.cn/c6/f0/c6f01b0c72ca774cbd62a6038421583f_1062x157.png)
然后,拷贝这个地址,比如我这里为:
```
D:\openSourceLearnProject\Android\CustomView\myapplication\build\intermediates\javac\debug\classes\com\weizu\jnitest\JNITest.class
```
然后执行:
```
javap -s D:\openSourceLearnProject\Android\CustomView\myapplication\build\intermediates\javac\debug\classes\com\weizu\jnitest\JNITest.class
```
即可得到方法签名:
![](https://img.kancloud.cn/2f/d3/2fd3042c3dfbe0bc11d050e9f7408493_424x186.png)
当然,我这里所需要的不是这个类,我所需要的是上面的JavaMethod 类,这里再次执行一下对应的javap命令,可以得到:
![](https://img.kancloud.cn/0f/cc/0fccfcea2ecda3721f4d1708b0da1e0e_460x233.png)
# 3. C语言中反射Java非静态方法
对应的在上一个案例中的native-lib.cpp中将之前的:
~~~
// native-lib.cpp
#include "com_weizu_jnitest_JNITest.h"
extern "C" jstring Java_com_weizu_jnitest_JNITest_helloJni(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
~~~
修改为:
~~~
#include "com_weizu_jnitest_JNITest.h"
#include <android/log.h>
#define LOG_TAG "System.out"
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
// 在这个方法中进行C调java的反射
extern "C" jstring Java_com_weizu_jnitest_JNITest_helloJni(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C++";
// 1. 字节码
jclass jclazz = (*env).FindClass("com/weizu/jnitest/JavaMethod");
// 2. 方法add
jmethodID jmethodId = (*env).GetMethodID(jclazz, "add", "(II)I");
// 3. 实例化类
jobject jobjectInstance = (*env).AllocObject(jclazz);
// 4. 调用方法
jint result = (*env).CallIntMethod(jobjectInstance, jmethodId, 24, 26);
LOGE("在C语言中计算结果为:%d\n", result);
return env->NewStringUTF(hello.c_str());
}
~~~
因为在MainActivity中调用了这个方法,且打印结果在日志中:
~~~
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Log.e("TAG", "onCreate: ${JNITest().helloJni()}" )
}
}
~~~
直接运行程序,查看一下日志信息,就可以知道是否成功:
![](https://img.kancloud.cn/2c/b0/2cb0d57bdcb83fa790a326f542a8488f_1188x248.png)
# 4. C语言中反射Java静态方法
我们在写Java中的反射的时候已经比较熟悉了,这里将上面的方法做一个简单的修改:
~~~
// 在这个方法中进行C调java的反射
extern "C" jstring Java_com_weizu_jnitest_JNITest_helloJni(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C++";
// 1. 字节码
jclass jclazz = (*env).FindClass("com/weizu/jnitest/JavaMethod");
// 2. 方法add
jmethodID jmethodId = (*env).GetStaticMethodID(jclazz, "showInfo", "()V");
// 静态方法不需要实例化类
// jobject jobjectInstance = (*env).AllocObject(jclazz);
// 3. 调用方法
(*env).CallStaticVoidMethod(jclazz, jmethodId);
LOGE("在C语言中调用了Java的静态方法。\n");
return env->NewStringUTF(hello.c_str());
}
~~~
![](https://img.kancloud.cn/82/76/827635982e734996361e2b32f60a6d70_990x241.png)
- 介绍
- UI
- MaterialButton
- MaterialButtonToggleGroup
- 字体相关设置
- Material Design
- Toolbar
- 下拉刷新
- 可折叠式标题栏
- 悬浮按钮
- 滑动菜单DrawerLayout
- NavigationView
- 可交互提示
- CoordinatorLayout
- 卡片式布局
- 搜索框SearchView
- 自定义View
- 简单封装单选
- RecyclerView
- xml设置点击样式
- adb
- 连接真机
- 小技巧
- 通过字符串ID获取资源
- 自定义View组件
- 使用系统控件重新组合
- 旋转菜单
- 轮播图
- 下拉输入框
- 自定义VIew
- 图片组合的开关按钮
- 自定义ViewPager
- 联系人快速索引案例
- 使用ListView定义侧滑菜单
- 下拉粘黏效果
- 滑动冲突
- 滑动冲突之非同向冲突
- onMeasure
- 绘制字体
- 设置画笔Paint
- 贝赛尔曲线
- Invalidate和PostInvalidate
- super.onTouchEvent(event)?
- setShadowLayer与阴影效果
- Shader
- ImageView的scaleType属性
- 渐变
- LinearGradient
- 图像混合模式
- PorterDuffXfermode
- 橡皮擦效果
- Matrix
- 离屏绘制
- Canvas和图层
- Canvas简介
- Canvas中常用操作总结
- Shape
- 圆角属性
- Android常见动画
- Android动画简介
- View动画
- 自定义View动画
- View动画的特殊使用场景
- LayoutAnimation
- Activity的切换转场效果
- 属性动画
- 帧动画
- 属性动画监听
- 插值器和估值器
- 工具
- dp和px的转换
- 获取屏幕宽高
- JNI
- javah命令
- C和Java相互调用
- WebView
- Android Studio快捷键
- Bitmap和Drawable图像
- Bitmap简要介绍
- 图片缩放和裁剪效果
- 创建指定颜色的Bitmap图像
- Gradle本地仓库
- Gradle小技巧
- RxJava+Okhttp+Retrofit构建网络模块
- 服务器相关配置
- node环境配置
- 3D特效