之前使用到JNI中,都是通过javah命令生成对应c/c++中的方法名,其规则为:java的包名+native方法名,我们把它称作静态注册。 JNI还可以使用动态注册,在JNI源码中,安卓系统(PathClassLoader)加载so文件时,首先会调用一个方法:JNI_OnLoad;这是系统预留给外部使用动态注册使用的,今天来使用动态注册的方式调用 void *) native_stringFromJNI } }; 每个元素中,第一个参数为Java中对应的方法,第二个参数为方法签名,第三个参数为c/c++中的函数指针,接下来写一个注册 总结: 静态注册: 每个class都需要使用javah生成一个头文件,并且生成的名字很长书写不便;初次调用时需要依据名字搜索对应的JNI层函数来建立关联关系,会影响运行效率 用javah 生成头文件方便简单 动态注册: 使用一种数据结构JNINativeMethod来记录java native函数和JNI函数的对应关系 移植方便(一个java文件中有多个native方法,java文件的包名更换后)
静态注册和动态注册 静态注册 默认情况下,就是静态注册,静态注册是最简单的方式,NDK开发过程中,基本上使用静态注册。前面的知识都是静态注册的方式。 优点: 开发简单 缺点: JNI函数名非常长 捆绑 上层 包名 + 类名 运行期 才会去 匹配JNI函数,性能上 低于 动态注册 动态注册 再看Android Framework源代码的Native 层,Android 系统的C++源码:基本上都是动态注册。 动态注册是怎么玩转的? 明白一个简单的道理,Java中我们new 类,默认会调用构造函数,重写了构造函数,就会调用我们自己的。 case R.id.jni_regist_1: dynamicJavaM01(); break; case R.id.jni_regist_2:
[logo] Spring之动态注册bean 什么场景下,需要主动向Spring容器注册bean呢? 如我之前做个的一个支持扫表的基础平台,使用者只需要添加基础配置 + Groovy任务,就可以丢到这个平台上面来运行了,而这个基础平台是一直都在运行的,所以在新来任务时,最直观需要注册的就是 DataSource 主动注册Bean支持 借助BeanDefinition来实现bean的定义,从最终的使用来看,代码比较少,几行而已 public <T> T registerBean(String name, Class = registerBean("test2", InrSer.class, "一灰灰Blog", 20); System.out.println(ser2); } @ToString 一灰灰Blog: https://liuyueyi.github.io/hexblog 一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛 2.
一.动态注册和静态注册 注册native方法有两种方式,动态注册和静态注册。 而动态注册是在运行时进行注册的,而且本地方法的名字可以按自己的喜好随意取,只要说明了java中声明的native方法和c/c++中的本地方法的对应关系即可。 下面用代码的形式来演示一下动态注册的使用步骤。 add(int a,int b); } 2.注册函数:在java中加载动态库的时候,虚拟机会调用JNI库中的JNI_Onload()函数,动态注册就是在这个函数中进行的。 动态注册使用的是RegisterNatives()方法,这个方法接收3个参数,分别是: 1.jclass clazz 声明native方法的java类 2.const JNINativeMethod
JNI方法注册源码分析(JNI_OnLoad|动态注册|静态注册|方法替换) [icon13-png-ed.png] 背景 开发Android应用时,有时候Java层的编码不能满足实际需求,需要通过JNI 入门选手可以采用Native方法动态注册,混淆方名。 文章指在学会使用JNI方法动态注册,静态注册,方法替换,且在这个过程中稍微了解一下native层的动态库加载,方法加载等知识。 (JNIEnv *env, jobject /* this */) { return env->NewStringUTF("Hello from C++ dynamic\n"); } 经过动态注册之后 优点 简单明了 so方法动态注册 这种方式,写的代码稍微多点,但好处很明显,函数映射关系配置灵活,执行效率要比第一种方式高。 JNINativeMethod是动态注册方法需要的结构体: typedef struct { const char* name;//在java中声明的native函数名 const char*
使用Spring期间可能会遇上需要动态注册bean的时候,此时可以通过如下实现: 基本步骤 //将applicationContext转换为ConfigurableApplicationContext 此属性引用已经定义的bean:userAcctDAO beanDefinitionBuilder.addPropertyReference("userAcctDAO", "UserAcctDAO"); // 注册
AllSele.CheckedChanged += new EventHandler(AllSele_CheckedChanged); int i = 2;
一、静态广播注册 MainActivity.java public class MainActivity extends AppCompatActivity { @BindView(R.id.btn_send :StaticBR.java /** * 作者:张风捷特烈 * 时间:2018/4/14:16:22 * 邮箱:1981462002@qq.com * 说明:静态注册广播接受者 */ public aii_broadcastreceiver", "com.toly1994.aii_broadcastreceiver.StaticBR")); ---- 二、动态注册 在未注册之前,点击发送无效果,在注册后点击发送有效果,在注销之后点击无效果。 动态注册广播.gif 注册方法: IntentFilter filter = new IntentFilter(); filter.addAction("com.toly1994.aii_broadcastreceiver.register
本文档描述freeswitch的动态配置SIP账户,以及动态修改拨号方案的问题。 bindings="dialplan" 表示该接口返回拨号方案信息 2、 动态配置SIP信息 修改好配置文件后,freeswitch获取验证sip注册信息时,将调用接口:directory来进行获取注册信息 /directory,如下 1.png 2.png 1、根据参数action参数判断用户的动作信息,获取参数中的sip帐号信息 2、根据sip帐号信息,从数据库查询相应的用户信息 3、用户为空时直接返回注册失败的 map,调动方法:replaceArgsNew,或者使用beel工具类,根据模版生成注册的xml信息 备注: 1、 模版文件内容 3.png 2、 注册失败的模版 4.png 3、工具类:replaceArgsNew // 加一个空行(结束行) } 3、 使用beel工具类处理模版信息时,项目需要导入jar包:antlr4-runtime-4.7.1.jar,beetl-core-2.2.3.jar,按需配置 3、动态配置拨号方案
Native 方法的静态注册 NDK 开发中,通过 javah -jni 命令生成的包含 JNI 的头文件,接口的命名方式一般是: Java_<PackageName>_<ClassName>_<MethodName 程序执行时系统会根据这种命名规则来调用对应的 Native 方法,这种注册方式称之为静态注册。 Native 方法的动态注册 由于静态注册存在命名局限性,生产环境中一般不采用静态注册的方式。动态注册的优点是可以自由命名 Native 方法,缺点是如果 Native 方法过多,操作比较麻烦。 动态注册的时机是在加载函数库(.a 或 .so)的时候进行注册,即在 JNI_OnLoad 方法里进行注册。 = JNI_TRUE) return JNI_ERR; return JNI_VERSION_1_6; } 以上 3 步便可实现动态注册。 -- END --
举个例子: 动态注册自己的beanDefinition,加载classpath之外的bean ---- 接口的继承关系 接口方法 void postProcessBeanDefinitionRegistry BeanDefinitionRegistry registry) throws BeansException; 入参 为 接口 BeanDefinitionRegistry 主要看提供的接口方法,可以发现提供的方法来主要有注册 postProcessBeanFactory方法 invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); ---- 示例 注册 prefix1.datasource.url= * prefix1.datasource.username= * prefix1.datasource.password= * * prefix2. datasource.driver= * prefix2.datasource.url= * prefix2.datasource.username= * prefix2.datasource.password
前言 本文的素材来自读者的一个问题,他看过我之前写的一篇博文聊聊如何把第三方服务注册到我们项目的spring容器中。 今天就来聊一下这个话题,为什么使用registerSingleton()注册的bean,无法使AOP生效 问题根源 registerSingleton()这个方法直接将bean存放到单例池里面了。 new出来的,就是一个普通的对象,因此注入到IOC容器后,也只是一个普通的bean,并没有任何增强 问题修复 方案一:不使用registerSingleton(),而是使用BeanDefinition注册方式
根据资料,该接口的主要作用就是用来动态的注入bean到spring ioc中。但是问题是什么是动态,或者怎么样的操作才算是动态。难道以前都不算动态吗。 作者对这里的动态的理解是可以用户自定义的决定注入哪些类。这里的自定义就是规则。根据作者的实践,认为就是注入作者自定义的注解的bean到ioc容器中。那么如何实现一个自定义的动态注入器。 ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) public @interface TianMapper { } 2.
【Android】JNI静态与动态注册介绍 JNI的两种注册机制:静态注册和动态注册. 方式: 静态注册 动态注册:需要提供Java中Native方法的方法签名和Native层中对应的实现函数。 静态注册 要求C/C++层的函数名符合某种特定的要求:包含Java中Native方法的目录信息和方法名。 动态注册 动态注册相对于静态注册,优点是不再根据特定路径查找函数的实现,带来两个好处: 没有了冗杂的函数名,适用于大型项目开发。 一种可行的方法是基于JNI重载JNI_OnLoad(),在其中对函数进行动态注册。
核心实现类 以前也写过关于动态注册Bean的博文,如 180804-Spring之动态注册bean 我们的实现方式和上面也没什么区别,依然是借助BeanDefinition来创建Bean定义并注册到BeanFactory applicationContext.getBean(name, clazz); } } 上面唯一的方法中,接收四个参数,源码中也有说明,稍微需要注意下的是Spring容器中不允许出现同名的Bean 2. 测试用例 动态创建Bean,并不是塞入容器之中就完结了,塞进去之后,是为了后续的使用,自然而然的就会有下面几种情形 a. Bean实例,使用supply接口, 可以创建一个实例,并主动注入一些依赖的Bean;当这个实例对象是通过动态代理这种框架生成时,就比较有用了 BeanDefinitionBuilder ,这个接口提供了两个方法,通常实现第一个方法来做Bean的注册;两者从根本上也没太大的区别,上面只是给出了一种使用演示 2.
这就是静态注册 动态注册:上面类似一张静态表,但是如果每个JNI的方法与Java的代码有个映射表,只要将这张表告诉JVM,那就可以找到对应的C++方法了 静态注册 对于静态注册,JNI的方法命名规则为: 动态注册 动态注册的关键字是两个: JNI_OnLoad()方法,这个是载入Jni库后调用的第一个方法,在这里可以将方法对应表注册给JNI环境 JNINativeMethod结构,这个结构是将jni层的方法映射到 static {}; descriptor: ()V} 其中descriptor就是对应的签名,比如方法"sayHello"对应的方法签名就是"()Ljava/lang/String;" 静态注册与动态注册的区别 静态注册,每次使用native方法时,都要去寻找;而动态注册,由于有张表的存在,因此查找效率高。 编译 上面不管是静态注册方法,还是动态注册方法,都需要将cpp文件编译成平台所需要的库。 总结 上面主要是我自己从使用NDK开发中体会到的需要掌握的东西,最主要是静态注册与动态注册的实现。后面会介绍Java和JNI层如何互相作用,敬请期待。
动态注册方法 RegisterNatives ( 核心重点 ) VII . 动态注册流程完整代码 I . , "(I)I", (void *)dynamicRegisterCMethod2} }; ③ 编写 JNI_OnLoad 方法 : 在该方法中进行 JNI 方法动态注册操作 ; int JNI_OnLoad 动态注册对应的 C/C++ 本地方法 参数情况 : ① 传递参数 : 如果动态注册的方法需要传递参数 , 需要加上 前面的 JNIEnv *env, jobject obj 两个参数 jint dynamicRegisterCMethod2 , "(I)I", (void *)dynamicRegisterCMethod2} }; /* 动态注册的 Java 类名称 注意 : 包名类名之间使用 "/" 分割 */ 动态注册 //1 . 获取 JNIEnv JNI 环境 , 需要从 JavaVM 获取 JNIEnv *env = nullptr; //2 .
例如24-17-16-1,其实25-24-23…3-2-1更长,事实上这是最长的一条。 输入格式: 第1行: 两个数字r,c(1< =r,c< =100),表示矩阵的行列。 第2..r+1行:每行c个数,表示这个矩阵。 输出格式: 仅一行: 输出1个整数,表示可以滑行的最大长度。 样例输入 5 5 1 2 3 4 5 16 17 18 19 6 15 24 25 20 7 14 23 22 21 8 13 12 11 10 9 样例输出 25 ---- 分析题目
CGLIB 动态代理机制 JDK 动态代理有一个最致命的问题是其只能代理实现了接口的类。为了解决这个问题,我们可以用 CGLIB 动态代理机制来避免。 String message) { System.out.println("send message:" + message); return message; } } 2. CGLIB 动态代理对比 JDK 动态代理只能代理实现了接口的类,而 CGLIB 可以代理未实现任何接口的类。 静态代理和动态代理的对比 灵活性 :动态代理更加灵活,不需要必须实现接口,可以直接代理实现类,并且可以不需要针对每个目标类都创建一个代理类。 而动态代理是在运行时动态生成类字节码,并加载到 JVM 中的。
注册进去了。怎么做的呢? 控制器: 视图: 即可。