前言: 在项目过程中遇到一个需求, 要集成第3方公司提供的滤镜功能, 第3方提供了对外接口的.h头文件和实现so库, 项目需要整合第3方so库到自己的so库中
1: 新建android工程, 建立jni目录, 在jni目录新建ImageAlogrithm目录, 放入第3方公司提供的.h头文件,
在jni目录下放入第3方提供的实现so库文件libImageAlorgrithm.so
2 编写对应的Android.mk文件:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := ImageAlogrithm
LOCAL_SRC_FILES := libImageAlogrithm.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/ImageAlogrithm
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := neosharePragueFilters
LOCAL_SRC_FILES := neosharePragueFilters.c
LOCAL_SDK_VERSION := 9
LOCAL_SHARED_LIBRARIES := libImageAlogrithm
LOCAL_LDLIBS := -llog -ljnigraphics
include $(BUILD_SHARED_LIBRARY)
3 编写实现的c文件,native方法和C/C++ 函数有两种对应方式,一种是静态注册,即 Java_包名_类名_方法名对应,另一种通过重写JNI_OnLoad函数实现动态注册。我们使用第2种方式。
#include <string.h> #include <jni.h> #include <NubiaEffectInterface.h> #include <android/bitmap.h> #define JNIREG_CLASS "cn/nubia/prague/PragueFilterNative" void applyFilter(JNIEnv* env, jobject thiz, jobject bitmap, jint width, jint height, jint index) { char* destination = 0; AndroidBitmap_lockPixels(env, bitmap, (void**) &destination); int tot_len = height * width * 4; int i; unsigned char * dst = destination; unsigned char * pTemp = malloc(tot_len * sizeof(unsigned char)); NubiaFunctionRGBA8888ToBGRA8888(pTemp, dst, width, height); char * effect; switch (index) { case 1: effect = "LOMO_effect"; break; case 2: effect = "gray-scale"; break; case 3: effect = "miniature"; break; case 4: effect = "sketch"; break; case 5: effect = "pragueThree"; break; case 6: effect = "emboss_effect"; break; default: break; } NubiaFunctionSpecialEffectBGRA8888InAndRGBA8888Out(effect, pTemp, dst, width, height); free(pTemp); AndroidBitmap_unlockPixels(env, bitmap); } /** * Table of methods associated with a single class. */ static JNINativeMethod gMethods[] = { { "nativeApplyFilter", "(Landroid/graphics/Bitmap;III)V", (void *)applyFilter}, //绑定 }; /* * Register several native methods for one class. */ static int registerNativeMethods(JNIEnv* env, const char* className, JNINativeMethod* gMethods, int numMethods) { jclass clazz; clazz = (*env)->FindClass(env, className); if (clazz == NULL) { return JNI_FALSE; } if ((*env)->RegisterNatives(env, clazz, gMethods, numMethods) < 0) { return JNI_FALSE; } return JNI_TRUE; } /** * Register native methods for all classes we know about. */ static int registerNatives(JNIEnv* env) { if (!registerNativeMethods(env, JNIREG_CLASS, gMethods, sizeof(gMethods) / sizeof(gMethods[0]))) return JNI_FALSE; return JNI_TRUE; } JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) { JNIEnv* env = NULL; jint result = -1; if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) { return result; } if (!registerNatives(env)) { //register return result; } result = JNI_VERSION_1_4; return result; }
其中applyFilter函数中调用的NubiaFunctionRGBA8888ToBGRA8888和 NubiaFunctionSpecialEffectBGRA8888InAndRGBA8888Out函数的由第3方提供so库实现,并定义在对外的头文件里。 由此整个工作就大功告成