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种。下篇再说。。。