Android jni 实例
在external 目录下添加新目录hellolib, 并添加hellolib.cpp 和Android.mk文件。 Hellolib.cpp 的内容如下: #include <jni.h> #define LOG_TAG "TestLib" #undef LOG #include <utils/Log.h> extern "C" JNIEXPORT void JNICALL Java_com_test_TestHelloLib_printHello(JNIEnv * env, jobject jobj) { LOGD("Hello LIB wktwkt wktwkt !/n"); } extern "C" JNIEXPORT void JNICALL Java_com_test_TestHelloLib_printHelloArg(JNIEnv *env, jobject jobj, jstring s) { const char *pathStr = env->GetStringUTFChars(s, NULL); LOGD("wwwwwwkkkkkkkkkkktttttt : %s/n", pathStr); env->ReleaseStringUTFChars(s, pathStr); } 注意这里的函数名需要按照JNI的规范(因此也可以用javah -jni工具来生成头文件,来保证函数名的正确性),Java_com_test_TestHelloLib_printHello的命名对应后面在java代码中,package名字是com.test,类名是TestHelloLib,native函数名是printHello和printHelloArg。 另外,LOGD及#define LOG_TAG "TestLib"等打印log的方式是采用了Android所提供的LOG机制,这样才能通过Android的logcat工具看到log。 用于编译C模块的Android.mk文件内容如下: LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:= / hellolib.cpp LOCAL_C_INCLUDES := / $(JNI_H_INCLUDE) LOCAL_SHARED_LIBRARIES := / libutils / libcutils LOCAL_PRELINK_MODULE := false LOCAL_MODULE := libhello include $(BUILD_SHARED_LIBRARY) 该文件中的一些变量分别对应的含义如下: LOCAL_SRC_FILES – 编译的源文件 LOCAL_C_INCLUDES – 需要包含的头文件目录 LOCAL_SHARED_LIBRARIES – 链接时需要的外部库 LOCAL_PRELINK_MODULE – 是否需要prelink处理 LOCAL_MODULE – 编译的目标对象 BUILD_SHARED_LIBRARY – 指明要编译成动态库 接下来回到Android顶层目录,并执行make libhello来编译: build/core/product_config.mk:207: WARNING: adding test OTA key ============================================ TARGET_PRODUCT=generic TARGET_BUILD_VARIANT=eng TARGET_SIMULATOR= TARGET_BUILD_TYPE=release TARGET_ARCH=arm HOST_ARCH=x86 HOST_OS=linux HOST_BUILD_TYPE=release BUILD_ID= ============================================ build/core/main.mk:178: implicitly installing apns-conf_sdk.xml target thumb C++: libhello <= external/hellolib/hellolib.cpp target SharedLib: libhello (out/target/product/generic/obj/SHARED_LIBRARIES/libhello_intermediates/LINKED/libhello.so) target Non-prelinked: libhello (out/target/product/generic/symbols/system/lib/libhello.so) target Strip: libhello (out/target/product/generic/obj/lib/libhello.so) Install: out/target/product/generic/system/lib/libhello.so 具体Eclipse环境的搭建请参考Android SDK文档中的详细说明,及Hello Android程序的创建过程,这里仅给出我们需要修改的TestHelloLib.java文件: public class TestHelloLib extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); System.load("/data/libhello.so"); printHello(); printHelloArg("wktTestTestTest"); } private native void printHello(); private native void printHelloArg(String arg); } 将TestHelloLib.apk 和libHello.so 部署到手机仿真器上。 Adb install TestHellolib.apk Adb push libhello.so /data 要验证其效果需要用Android的logcat工具来查看。运行”adb logcat”可以找到下面的log片断: b: pid=502 uid=10024 gids={} I/jdwp ( 502): received file descriptor 10 from ADB D/dalvikvm( 502): Trying to load lib /data/libhello.so 0x4341bf28 D/dalvikvm( 502): Added shared lib /data/libhello.so 0x4341bf28 D/dalvikvm( 502): No JNI_OnLoad found in /data/libhello.so 0x4341bf28 D/dalvikvm( 502): +++ not scanning '/system/lib/libwebcore.so' for 'printHello' (wrong CL) D/dalvikvm( 502): +++ not scanning '/system/lib/libmedia_jni.so' for 'printHell o' (wrong CL) D/TestLib ( 502): Hello LIB wktwkt wktwkt ! D/dalvikvm( 502): +++ not scanning '/system/lib/libwebcore.so' for 'printHelloA rg' (wrong CL) D/dalvikvm( 502): +++ not scanning '/system/lib/libmedia_jni.so' for 'printHell oArg' (wrong CL) D/TestLib ( 502): wwwwwwkkkkkkkkkkktttttt : wktTestTestTest I/ActivityManager( 47): Displayed activity com.test/.TestHelloLib: 426 ms D/dalvikvm( 89): GC freed 1403 objects / 74632 bytes in 104ms D/dalvikvm( 83): GC freed 15971 objects / 524400 bytes in 180ms 还是用libhello.so 举例, 将libhello.so 1. 编写c模块, 实现动态库
2. 编写Java模块
3. 集成测试
4. so 文件打包发布