`

JNI学习--Java监听器全局监控

    博客分类:
  • java
 
阅读更多

1.前段时间,闲来无聊,想做个像QQ截图一样的截图工具,在却在做的过程中发现java自带API中的监听器带有很大的局限性,java的鼠标监听器只有在鼠标在程序窗口之上时才会生效,而键盘监听器则更加局限,只有在当前窗口为焦点窗口时才会生效,这显然是不符合我们需要效果的,我们所需要的是全局的键盘监听,不管你在干什么,只要触发我们设定的固定的组合键是,就会执行我们需要的功能,所以用java是不太好办。

    2.那么QQ是怎么做到的呢?QQ是用C语言写的,并不是java,而且windows也是C语言写出来的,所以他能轻易的实现这种全局监听。这也就是一个突破口,native,不知道你有没有注意过这个关键字,这是用来调用本地代码的一个关键字。我们可以这样设想,假如我们将所有的代码全部用java实现,却用C语言去监听全局键盘,然后返回为我们所用。是不是很有意思。

    3.下面我来说明这样用java代码调用C语言的方法(函数)。

Java代码 复制代码 收藏代码
  1. package test;   
  2. public class HelloWorld{   
  3.          static{   
  4.                  System.loadLibrary("HelloDll");   
  5.          }     
  6.          public static void main(String args[]){   
  7.                  HelloWorld hw = new HelloWorld();   
  8.                  hw.sayHello();   
  9.          }   
  10.          public native void sayHello();   
  11. }  
package test;
public class HelloWorld{
         static{
                 System.loadLibrary("HelloDll");
         }  
         public static void main(String args[]){
                 HelloWorld hw = new HelloWorld();
                 hw.sayHello();
         }
         public native void sayHello();
}

       上面这个System.loadLibrary("HelloDll");此句为引入一个叫做HelloDll的本地文件,而这个必定包含了sayHello();的实现代码。java工作我们算是昨晚了,也就是一个简单的打印HelloWorld的代码,重要的是我们怎样用C语言去实现这个本地方法,怎样让其经行工作。

       (1).编写java文件。上一步已经实现

       (2).javac运行源文件生成class文件

       (3).javah test.HelloWorld 这里注意不用上带后缀,我在经行这一步骤时,路径问题很麻烦。在包这一层运行javah test.HelloWorld就会生成一个叫test_HelloWorld.h的C语言头文件。

    因为我们的方法是要用C语言实现的,所以经行到这一步,我们得到了一个C的头文件。如果你打开这个头文件,你会发现里面会有一个叫做JNIEXPORT void JNICALL Java_test_HelloWorld_sayHello(JNIEnv *, jobject);的方法,这个方法其实就是我们的java方法在C语言里边的映射了(我一般这么称呼,不知道对不对),我们只要将这个方法用C语言实现了,然后编译成一个java能调用的DLL本地文件就OK了。

       (4)打开Microsoft Visual C++,File-->new-->Win32 Dynamic-Link Library,新建一个叫HelloDLL的文件动态链接工程,点击左下角FileView,点开HelloDll files。然后File-->new-->C/C++ Header File,名字为test_HelloWorld.h,然后点开Header Files里的test_HelloWorld.h,将我们刚才生成的test_HelloWorld.h文件内容复制进去,再File-->new-->C++ Source File,名字hello(随便取),然后点开文件写入内容:

Cpp代码 复制代码 收藏代码
  1. #include "test_HelloWorld.h"   
  2. #include <iostream.h>   
  3. JNIEXPORT void JNICALL Java_test_HelloWorld_sayHello   
  4.     (JNIEnv *, jobject){   
  5.         cout<<"HelloWorld"<<endl;   
  6. }  
#include "test_HelloWorld.h"
#include <iostream.h>
JNIEXPORT void JNICALL Java_test_HelloWorld_sayHello
    (JNIEnv *, jobject){
		cout<<"HelloWorld"<<endl;
}

       可以看出,我们生成头文件的目的,无非就是为了用C语言实现,因为我们这里引入了这个头文件,而这里边唯一的一个方法,就是我们生成的头文件,也就是我们的java代码未实现的代码在C中的映射,然后我在这个方法中打印了HelloWorld这句话。(如果看不懂C代码,建议百度一下,就算看不懂,凭我文字描述应该也是能懂一些的,不过应该不会看不懂吧)。

 

       另外就是,这一个段落我写的比较详细,甚至比较啰嗦,主要是为了没用过Microsoft Visual C++或者没学过C的人,能够手把手的教他运行这个程序,大神可以略过。

       好了,言归正传,我们还需引入java的lib环境,Tools-->Options-->Directories在底下的方框栏中加入你C:\PROGRAM FILES\JAVA\JDK1.6.0_04\INCLUDE和C:\PROGRAMFILES\JAVA\JDK1.6.0_04\INCLUDE\WIN32也就是java的JDK的include和include中win32两个文件夹。然后Build-->Rebuild All。

       你会发现,在你C++文件夹HelloDll中Debug中有一个HelloDll.dll文件。那么这个文件就是我们需要的动态链接文件了。如果你将它打开,那么你会发现大部分是乱码。

    (5)将得到的HelloDll.dll复制到你的java工程的包这一层下,然后运行java test.eHelloWorld,就会打印HelloWorld这句话了,如果在没有这个dll文件时你就引进运行了,会抛出一个找不到动态链接文件的异常。

    (6)这样我们就实现了用java调用C语言的方法了。这就是动态链接了,在下一篇我将描述,怎样用C语言的HHOOK钩子去获取windows底层键盘和鼠标的相应。

分享到:
评论

相关推荐

    手把手教你实现Java监听器全局监控

    本教程将手把手教你如何实现Java监听器的全局监控,帮助你更好地理解这一核心概念并将其应用到实际项目中。 首先,我们要明白Java监听器的工作原理。在Java AWT和Swing库中,事件驱动模型是常见的设计模式,通过...

    Java监听键盘鼠标全局事件[定义].pdf

    JNI是Java监听键盘鼠标全局事件的基础技术。 二、Windows Hook Windows Hook是一种Windows操作系统提供的机制,可以捕捉系统事件,如键盘按键、鼠标点击等。Hook函数可以在事件发生时被调用,以便处理事件。 三、...

    在Windows下实现Java程序的屏幕鼠标键盘监控.pdf

    这里展示了如何在实际应用中集成这些监听器。 ### 在Windows环境下增强监控能力 尽管Java的内置事件监听机制提供了基础的键盘和鼠标监控功能,但在某些场景下,尤其是需要更高级别的监控(如系统级监控)时,这些...

    jnativehook_java键盘钩子_hookapi_jnativehook_

    标题中的“jnativehook_java键盘钩子_hookapi_jnativehook”指的是Java中使用JNativeHook库来实现系统级键盘钩子的功能。...在开发需要全局监控键盘事件的Java应用程序时,这是一个非常有用的工具。

    Java学习笔记_内存管理.rar

    常见的内存泄漏原因包括:全局变量、静态变量引用不再使用的对象,或者忘记取消监听器等。 4. **JVM调优**: - **JVM参数设置**:例如-Xms和-Xmx设置堆内存大小,-XX:NewRatio调整新生代和老年代的比例,-XX:...

    jwinkey:用于用Java编写的Windows的无窗口全局键和鼠标侦听器

    **金威基(jwinkey):Java实现的无窗口全局键鼠监听器** 金威基,即jwinkey,是一款专为Java开发者设计的工具,它能够在Windows操作系统上实现无窗口的全局键鼠监听功能。这个库允许程序员在不依赖任何特定窗口的...

    java内存泄露[文].pdf

    - Native内存泄露:Java程序使用JNI(Java Native Interface)调用C/C++代码时,如果不正确管理native内存,也可能发生内存泄露。 - 注册监听器未注销:事件监听器如果注册后没有在适当时候注销,可能导致持有大量...

    pyHook+swing

    2. 在Java应用中使用Jython(一个Python的Java实现)或者通过Java的Java Native Interface (JNI) 来调用Python脚本,这样Python可以利用pyHook监听系统级的键盘和鼠标事件。 3. 通过Java应用与Python脚本之间的通信...

    2012最新java面试大全--很有帮助的

    通常使用JNI(Java Native Interface)来实现Java层和原生层之间的通信。此外,还可以使用AIDL(Android Interface Definition Language)来实现跨进程通信。 ### 55. Android系统的垃圾回收机制是什么? Android...

    JSP中用回车监听按钮事件兼容火狐 IE等主流浏览器

    1. **Java监听器**:在Java中,我们可以使用监听器来监控应用程序中的特定事件,比如HTTP请求、用户交互等。例如,Servlet容器提供了一系列的监听器接口,如HttpSessionListener、ServletRequestListener等,我们...

    Android-Application--.rar_android开发_C++_

    - **JNI**(Java Native Interface):Java与本地代码之间的桥梁,用于调用C++函数或反之。 - **LLVM/Clang**:NDK中的编译器,支持C++11及更高版本,用于编译原生代码。 - **性能优化**:C++代码可以运行在硬件...

    附录E 关于垃圾收集的一些话.zip

    7. **内存泄漏**:虽然有了垃圾收集,但不恰当的编程习惯仍可能导致内存泄漏,如全局静态变量引用不再需要的对象,或者忘记取消注册监听器等。理解和避免这些陷阱是确保程序高效运行的关键。 8. **监控与调优**:...

    Android面试系列—目录

    - **全局监听**:监听Back键事件,实现全局退出逻辑。 #### 33. Android中XML解析方式及其优缺点 - **DOM解析**:将XML文档加载到内存中,适用于较小的文档。 - **SAX解析**:逐行解析XML文档,适用于大型文档。 - ...

    Android技术面试整理附有详细答案(包括百度、新浪、中科软等多家公司笔试面试题)

    - **Java中引用本地语言**: 通过JNI(Java Native Interface)来调用本地代码。 #### 39. IPC(进程间通信)机制 - **Binder**: Android中的IPC机制,用于实现不同进程间的通信。 #### 40. NDK - **NDK(Native ...

Global site tag (gtag.js) - Google Analytics