初识JNI(一)

JNI是Android的重要组成部分,它帮助我们解决了2件事。

1.JAVA函数可以直接调用native语言写的函数,一般指的是C,C++函数

2.native语言C,C++的函数可以调用java的函数,


总结,JNI是Native世界和JAVA世界的桥梁。

我们可能会接触到这样的类。

package com.vss.vssmobile.common;

import com.vss.vssmobile.entity.DeviceInfo;
import com.vss.vssmobile.entity.DirInfo;
import com.vss.vssmobile.listener.IORecvListener;

public class Zlvss {
	private Zlvss() {
	}

	private static final Zlvss zlvss = new Zlvss();

	public static Zlvss getInstance() {
		return zlvss;
	};

	static {
		try {
			System.loadLibrary("item1");
			System.loadLibrary("item2");
		} catch (UnsatisfiedLinkError ule) {
			System.out.println("loadLibrary(API)," + ule.getMessage());
		}

	}

	public native void sharedInstance();

	public native void destroyInstance();

	public native void setonRecvListener(IORecvListener i);
	public native void  clearRecvListener();

	public native int p2pserver_sdk_init(); // useless

	public native int return_p2pserver_status();

	public native int p2pserver_reconnect();

	public native int devmanager_get_devID_fromDeviceInfo(DeviceInfo info);

	public native DeviceInfo devmanager_get_devInfo_fromDevID(int devid);

	public native int devmanager_get_videoID_fromDevID(int devid, int chnnum);

	public native int devmanager_isConnectMainToDevice(int devid);

	public native int devmanager_isConnectSubToDevice(int devid);

	public native int devmanager_isConnectVideoToDevice(int devid, int chnnum);

	public native boolean devmanager_test_mainIsConnected(int devid);

	public native boolean devmanager_get_main_isProxy(int devid);

	public native boolean devmanager_get_sub_isProxy(int devid);

	public native boolean devmanager_get_video_isProxy(int devid, int num);

	public native int devmanager_addDevice_deviceInfo(DeviceInfo info);

	public native int devmanager_createDevice_deviceInfo(DeviceInfo info);

	public native void devmanager_deleteDevice_devID(int devid);

	public native int devmanager_loginToDevice_devID(int devid);

	public native boolean devmanager_setDevice_devID(int devid, int chnnum);

	public native void devmanager_logoutFromDevice_devID(int devid);

	public native int devmanager_checkUserLimitFromDevice_devID(int devid);

	public native int devmanager_connectVideoToDevice_devID(int devid, int num);

	public native void devmanager_disconnectVideoFromDevice_devID(int devid,
			int num);

	public native int devmanager_requestVideoFromDevice_devID(int devid,
			int num, int issub);

	public native int devmanager_stopVideoFromDevice_devID(int devid, int num,
			int issub);

	public native long devmanager_getVideoDataFlow_devID(int devid);
	public native int devmanager_startRecord_devID(int devid, int num,
			String path);

	public native void devmanager_stopRecord_devID(int devid, int num);

	public native int devmanager_openAlarmToDevice_devID(int devid,int num,int type);

	public native int devmanager_closeAlarmToDevice_devID(int devid,int num,int type);

	public native void  devmanager_ptzControl_devID (int devid,int num,int type);

	public native int devmanager_remoteKeyboard_devID(int devid, int btnid);

	public native int devmanager_connectSubToDevice_devID(int devid);

	public native int devmanager_disconnectSubFromDevice_devID(int devid);

	public native int playback_searchVideoFile_devID(int devid,int num,int year,int month,int day,int hour,int min,int second);

	public  native  int playback_searchDownloadVideoFile_devID(int devid,int num,int year1,
			int month1,int day1,int hour1,int min1,
			int second1,int year2,int month2,int day2,int hour2,int min2,int sencond2);

	public native int playback_requestVideoFile_devID(int devid, int num,
			int  position);

	public native int playback_requestDownloadVideoFile_devID(int devid,
			int num, DirInfo c);


	public native int playback_stopVideoFile_devID(int devid, int num);

	public native void playback_pauseVideoFile_devID(int devid);
	
	public native void playback_continueVideoFile_devID(int devid);
	
	public native void playback_quickPlayVideoFile_devID(int devid);

	public native void playback_slowPlayVideoFile_devID(int devid);

	public native void playback_playVideoFile_devID(int devid, int num,
			int c, double percent);

	public native int playback_startRecord_devID(int devid, String path);

	public native void playback_stopRecord_devID(int devid);

	public native int  zeroVideo_requestZeroVideo_devID (int devid,int param1,int param2);

	public native int  zeroVideo_stopZeroVideo_devID(int devid);
}

一上手,一堆的native方法。但他又不是接口类型的,这样的话,它是怎么调用的呢,首先你可以安卓项目的libs库里找到libitem1.so和libitem2.so类似的文件,这个就是动态库,Linux以so为后缀名,

这样就找到了native世界和JAVA世界2边程序员需要做的事。 JAVA程序员根据需求编写如上文件,在实际的应用场景来调用这些native函数。

然后native层C,C++程序员做具体的实现。


tips: so文件一般以lib+名称+.so命名。如libitem1.so.

其次必须准确的规范JAVA层的输入参数和返回类型,不然可能需要重新编译。

JAVA在这个类加载的时候,会加载到static 代码,里面加载了2个so。不然你无法找到Native函数的具体实现。

但这个native函数是如何对应C,C++层的具体实现的呢。

有静态注册和动态注册2种。下篇再说。。。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当您在Java程序中需要调用C/C++代码时,可以使用Java Native Interface(JNI)来实现。下面是一个简单的JNI示例,演示了如何将Java方法与C函数相互调用: 1. 创建一个Java类,例如"JNIDemo.java",其中包含您想要调用的本地方法: ```java public class JNIDemo { // 本地方法声明 public native void sayHello(); // 加载本地库 static { System.loadLibrary("jni_demo"); // 加载名为"jni_demo"的本地库 } // 测试 public static void main(String[] args) { JNIDemo demo = new JNIDemo(); demo.sayHello(); // 调用本地方法 } } ``` 2. 在命令行中使用`javac`编译Java类:`javac JNIDemo.java`。 3. 生成C头文件,可以使用`javah`工具:`javah JNIDemo`。这将生成名为"JNIDemo.h"的头文件。 4. 创建一个C源文件,例如"jni_demo.c",实现您在Java中声明的本地方法: ```c #include <stdio.h> #include "JNIDemo.h" JNIEXPORT void JNICALL Java_JNIDemo_sayHello(JNIEnv *env, jobject obj) { printf("Hello from C!\n"); } ``` 5. 在命令行中使用C编译器编译C源文件,并生成共享库文件(DLL或SO): - 对于Windows(使用MinGW):`gcc -shared -I"%JAVA_HOME%\include" -I"%JAVA_HOME%\include\win32" jni_demo.c -o jni_demo.dll` - 对于Linux/Mac:`gcc -shared -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/linux" jni_demo.c -o libjni_demo.so` 注意:请将`$JAVA_HOME`替换为您Java安装的实际路径。 6. 运行Java程序:`java JNIDemo`。您将看到输出:"Hello from C!"。 这是一个简单的JNI示例,演示了如何在Java和C之间进行方法调用。您可以根据自己的需求扩展和定制此示例。希望对您有帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值