1.在jni调用其他动态库函数。
1.该动态库(.so)必须是android平台中的动态库。第三方库必须经过android移植后才能用。
2.在Android.mk中要LOCAL_LDLIBS := -lxxxx 选项(表示编译时要链接的动态库)。
如果在cygwin环境下编译jni动态库,还要将要用到的第三方库拷到D:\android-ndk-r8e\platforms\android-3\arch-arm\usr\lib中。
如有头文件可通过LOCAL_C_INCLUDES += $(LOCAL_PATH) (头文件在当前目录查找)配置,也可将头文件拷到D:\android-ndk-r8e\platforms\android-3\arch-arm\usr\include中
2.在jni中要对设备节点编程
在android应用程序中默认是没用root权限的,当你在linux下能够编译运行的程序,通过jni编译为动态库经app调用后,在eclipse编译为app始终会出错,这种情况下你要将所用到的设备节点权限改为777,还有就是通过server进行调用(这个我没试过)。
3.jni中传参问题
对于一般的传值都没用问题,对于数组的传值就会出现问题。
我在android应用程序中通过jni将数组传递到c函数,通过c函数向数组中填值再返回到app层,
在eclipse编译时会出现一些寄存器,堆栈的错误信息(有个signal 11的出错信息)。
在修改c函数通过malloc开辟一段空间返回指针到jni函数在赋值,eclipse编译又出现空指针异常的问题,
最后我只有在jni层直接返回一个数组了。
jbyteArray bytearray = (*env)->NewByteArray(env,len);
(*env)->SetByteArrayRegion(env,bytearray,0,len,buf);
return bytearray;
buf为c函数malloc后返回到jni的指针,len是返回的长度。这样app就获取到c函数层的数据了。
4.Android.mk常用语法
LOCAL_PATH := $(call my-dir)
STLPORT_FORCE_REBUILD := true
include $(CLEAR_VARS)
LOCAL_C_INCLUDES += $(LOCAL_PATH) 增加一个编译时头文件查找路径为当前路径
LOCAL_LDLIBS := -ljpeg 编译时依赖的动态库。
LOCAL_MODULE := hello-jni
LOCAL_SRC_FILES := hello-jni.c jpeg.c
include $(BUILD_SHARED_LIBRARY) 编译为动态库
include $(BUILD_STARIC_LIBRARY) 编译为静态态库
include $(BUILD_EXECUTABLE) 编译为可执行文件(在cygwin环境下的jni目录中编译,在libs/armeabi下会生成可执行文件)
5.jni中打印信息
1.增加头文件#include <android/log.h>
2.增加动态库LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog
3.输出格式__android_log_print(ANDROID_LOG_INFO,"JNIMsg","-------%p,%d",buf,len);前面为固定格式,后面同printf。
6.android应用程序将文件保存到sd卡
1.增加sd卡操作权限。
<application
**********************
</application>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
2.android程序
File sdCardDir = Environment.getExternalStorageDirectory();// 获取SDCard目录
File saveFile = new File(sdCardDir, "1.jpeg");
try {
FileOutputStream outStream = new FileOutputStream(saveFile);
outStream.write(buf, 0, buf.length);
outStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}