java jni & 反射草稿

JNI(Java Native Interface,Java本地接口)定义&作用: 用于打通Java层与Native(C/C++)层。
JNI注册的两种时机:
1)Android系统启动过程中Zygote注册,可通过查询AndroidRuntime.cpp中的gRegJNI,看看是否存在对应的register方法;
2)调用System.loadLibrary()方式注册。
JNI接口的组织类似于C++虚拟函数表,指向不同的接口函数
首先明白native方法名和文件名的命名规律,其次要懂得该如何去搜索代码。
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
JNI开发流程
从java层到c+层
在这里插入图片描述
参考:JNI动态注册 https://blog.csdn.net/hjf161105/article/details/79543808
编写java类,声明了native方法
编写native代码(c语言)
将native代码编译成so文件
在java类中引入so库,调用native方法
,
实例分析:引用自:https://www.cnblogs.com/anni-qianqian/p/5574039.html
使用C语言实现本地方法

  1. 在项目根目录下创建jni文件夹
  2. 在jni文件中创建一个c文件
  3. 在java代码中,创建一个本地方法helloFromC

//native关键字
public native String helloFromC();
4. 在jni中定义函数实现这个方法,函数名必须为

//返回值 报名_类名_方法名(参数参照例子)
jstring Java_com_itheima_helloworld1_MainActivity_helloFromC(JNIEnv* env, jobject obj)
5. 返回一个字符串,用c定义一个字符串

char* cstr = “hello from c”;
6. 把c的字符串转换成java的字符串

jstring jstr = (*env)->NewStringUTF(env, cstr);
return jstr;
7. 在jni中创建Android.mk文件
8. 在c文件中添加<jni.h>头文件
9. 在jni文件夹下执行ndk-build.cmd指令
10. java代码中加载so类库,调用本地方法(so是C语言的类库)

static{
//加载打包完毕的so类库
System.loadLibrary(“hello”);
}
代码

MainActivity

public class MainActivity extends Activity {

static{
    //加载打包完毕的so类库
    System.loadLibrary("hello");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}

public void click(View v){
    Toast.makeText(this, helloFromC(), 0).show();
}

//定义一个本地方法,方法体由c语言实现
public native String helloFromC();

}

Hello.c

#include <stdio.h>
#include <stdlib.h>
#include <jni.h>

jstring Java_com_itheima_helloworld1_MainActivity_helloFromC(JNIEnv* env, jobject obj){
//c语言的字符串
char* cstr = “hello from c”;
//把C语言的字符串转换成java的字符串
// jstring (NewStringUTF)(JNIEnv, const char*);
// jstring jstr = (*(*env)).NewStringUTF(env, cstr);
jstring jstr = (*env)->NewStringUTF(env, cstr);
return jstr;
}
Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
#编译生成的文件的类库叫什么名字
LOCAL_MODULE := hello
#要编译的c文件
LOCAL_SRC_FILES := Hello.c

include $(BUILD_SHARED_LIBRARY)

  • 实现两个数相加

public class MainActivity extends Activity {
static{
System.loadLibrary(“hello”);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}

public void click(View v){
    Toast.makeText(this, "3+5的和为" + add(3, 5), 0).show();
}

public native int add(int i, int j);

}
Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := hello
LOCAL_SRC_FILES := Hello.c

include $(BUILD_SHARED_LIBRARY)

Hello.c

#include <jni.h>

jint Java_com_itheima_helloworld2_MainActivity_add(JNIEnv* env, jobject obj, jint i, jint j){

return i + j;

}
Application.mk

APP_ABI := all //支持arm、mips、x86等所有架构

  • javah
      1.7:在src目录下执行javah 包名.类名
      1.6:在bin/classes目录下执行

然后工程刷新,复制里面已经自动生成的方法名,就可以粘贴到c文件中使用
,
https://blog.csdn.net/c10WTiybQ1Ye3/article/details/107010668
jni实例分析:https://www.jianshu.com/p/0f34c097028a
用了jni,在c文件中有了jint,jclass,jlong等是入参。是jini的int,long等类型。理解为jint=int
为java传入的参数。

  1. static register native function
  2. dynamic register native function
    i) coding java native function
    ii) product .h headfile
    iii) RegisterNatives:put c/c++ function map to java function
    JNI_OnLoad 即jni 的main

程序在启动的时候,并不会一次性加载程序所要用的所有class文件,而是根据程序的需要,
通过Java的类加载机制(ClassLoader)来动态加载某个class文件到内存当中的,
从而只有class文件被载入到了内存之后,才能被其它class所引用
,
反射:
在这里插入图片描述
运行状态获取class的对象,构造函数,方法等.
学习反射之前,需要先学习类的加载过程:Java虚拟机基础——3类加载机制:https://www.jianshu.com/p/443ca5b1e8b2
使用实例:
Class actionClass=Class.forName(“MyClass”);
Object action=actionClass.newInstance();
Method method = actionClass.getMethod(“myMethod”,null);
method.invoke(action,null);

反射:https://zhuanlan.zhihu.com/p/270939753
实例:https://lixuekai.blog.csdn.net/article/details/52255363
https://lixuekai.blog.csdn.net/article/details/52254924

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值