本文所讲内容有一下几个条件:
1.本文所讲内容适合Android系统移植和底层开发。
2.本地程序不是指的Java程序。而是运行在底层的c/c++程序。
3.编译环境为Android系统的源码,而不是NDK。
在编写Android程序的时候,有时候要去调用一些底层函数。尤其是自己添加了新的设备,有了新的驱动函数之后,则需要自己去编写一些Java接口。这里便用到了JNI这个技术。本文是由JNI延伸出来的。
首先以一个例子讲一下JNI,
如果我们想要一个打印字符的函数,则我们从java的那一层开始做起,首先编写函数如下:
public final class hello{
public static native String hello(String hello);
}
将其编译成.class文件,然后用javah生成c/c++所需的头文件。如图:
生成头文件如下:
对应头文件,我们编写相应的实现函数hello.c。
由于自己实在源码中编译,所以不需要NDK之类的东西,编写Android.mk如下:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SHARED_LIBRARIES := liblog libdl
LOCAL_INCLUDES += $(LOCAL_PATH)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES += hello.c
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE:= hello
include $(BUILD_SHARED_LIBRARY)
之后编译成动态库,如下:
这样,动态库便编写好了。Java程序中,直接用System.loadLibrary()调用就行了。
对于JNI,涉及到Android本地编译动态库的问题,那么编译可执行程序,可静态库应该怎么编译呢?其实非常简单,只要修改Android.mk中的参数就行了。
include $(BUILD_SHARED_LIBRARY)
上面Include里面的代表动态库,改成BUILD_EXECUTABLE就变成可执行文件,改成BUILD_STATIC_LIBRARY就生成静态库。就这么简单。
参考网站:http://www.cnblogs.com/MarsGG/articles/2057433.html
http://www.cnblogs.com/lilactutu/archive/2010/12/06/1897696.html