jni是java语言调用c代码的桥梁。 往往kernel的代码,需要通过jni来使用。
小米手机里 有个“色温和饱和度”功能,底层功能就设计到jni。
一、用来生成lib库的cpp文件:mhal_gammajni.cpp
//定义需要使用的函数
static jint getGammaRange(JNIEnv *env, jobject thiz)
{
//
}
static jint getGammaIndex(JNIEnv *env, jobject thiz)
{
//
}
static jboolean setGammaIndex(JNIEnv *env, jobject thiz , int index)
{
//
}
//JNI register
static const char *classPathName = "com/example/gamma/PictureQualityGammaJni";
static JNINativeMethod g_methods[] = {
{"nativeGetGammaRange", "()I", (void*)getGammaRange },
{"nativeGetGammaIndex", "()I", (void*)getGammaIndex },
{"nativeSetGammaIndex", "(I)Z", (void*)setGammaIndex}
};
/*
* Register several native methods for one class.
*/
static int registerNativeMethods(JNIEnv* env, const char* className,
JNINativeMethod* gMethods, int numMethods)
{
jclass clazz;
clazz = env->FindClass(className);
if (clazz == NULL) {
XLOGE("Native registration unable to find class '%s'", className);
return JNI_FALSE;
}
if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {
XLOGE("RegisterNatives failed for '%s'", className);
return JNI_FALSE;
}
return JNI_TRUE;
}
// ----------------------------------------------------------------------------
/*
* This is called by the VM when the shared library is first loaded.
*/
jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
JNIEnv* env = NULL;
jint result = -1;
XLOGI("JNI_OnLoad");
if (JNI_OK != vm->GetEnv((void **)&env, JNI_VERSION_1_4)) {
XLOGE("ERROR: GetEnv failed");
goto bail;
}
if (!registerNativeMethods(env, classPathName, g_methods, sizeof(g_methods) / sizeof(g_methods[0]))) {
XLOGE("ERROR: registerNatives failed");
goto bail;
}
result = JNI_VERSION_1_4;
bail:
return result;
}
其中,
1、classPathName 要知道我们自己的app中;
2、g_methods 定义 c 和 java 对应的函数名,规则可以上网查看;
3、JNI_OnLoad 调用lib库时条用;
二、通过各种方法生成lib库。 我这里在android源码中加入 android.mk编译。
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
mhal_gammajni.cpp
LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
LOCAL_C_INCLUDES += \
$(KERNEL_HEADERS) \
$(TOP)/frameworks/base/include \
$(TOP)/mediatek/platform/mt6582/kernel/drivers/dispsys
LOCAL_SHARED_LIBRARIES := \
libcutils \
libutils \
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE := libgammajni
LOCAL_MODULE_TAGS := eng
include $(BUILD_SHARED_LIBRARY)
1、LOCAL_MODULE := libgammajni 生成的lib库名称不要有大写字符,以免不能加载到 手机 system/lib下
三、与c代码对应的java文件:PictureQualityGammaJni.java
public class PictureQualityGammaJni {
private static final String TAG = "PictureQualityJni";
private PictureQualityGammaJni() {
}
static {
System.loadLibrary("gammajni");
System.loadLibrary("pqjni");
}
// gamma index
public static native int nativeGetGammaRange();
public static native int nativeGetGammaIndex();
public static native boolean nativeSetGammaIndex(int index);
public static native int nativeGetSkinToneHRange();
public static native int nativeGetSkinToneHIndex();
public static native boolean nativeSetSkinToneHIndex(int index);
public static native int nativeGetGrassToneHRange();
public static native int nativeGetGrassToneHIndex();
public static native boolean nativeSetGrassToneHIndex(int index);
public static native int nativeGetSkyToneHRange();
public static native int nativeGetSkyToneHIndex();
public static native boolean nativeSetSkyToneHIndex(int index);
public static native int nativeGetSkinToneSRange();
public static native int nativeGetSkinToneSIndex();
public static native boolean nativeSetSkinToneSIndex(int index);
public static native int nativeGetGrassToneSRange();
public static native int nativeGetGrassToneSIndex();
public static native boolean nativeSetGrassToneSIndex(int index);
public static native int nativeGetSkyToneSRange();
public static native int nativeGetSkyToneSIndex();
public static native boolean nativeSetSkyToneSIndex(int index);
public static native int nativeGetSharpAdjRange();
public static native int nativeGetSharpAdjIndex();
public static native boolean nativeSetSharpAdjIndex(int index);
public static native int nativeGetSatAdjRange();
public static native int nativeGetSatAdjIndex();
public static native boolean nativeSetSatAdjIndex(int index);
public static native int nativeGetHueAdjRange();
public static native int nativeGetHueAdjIndex();
public static native boolean nativeSetHueAdjIndex(int index);
public static native int nativeGetXAxisRange();
public static native int nativeGetXAxisIndex();
public static native boolean nativeSetXAxisIndex(int index);
public static native int nativeGetYAxisRange();
public static native int nativeGetYAxisIndex();
public static native boolean nativeSetYAxisIndex(int index);
}
1、可以同时加载多个lib库
System.loadLibrary("gammajni");
System.loadLibrary("pqjni");
2、与c代码对应的静态函数要写全,否则运行加载时要报错。
四、调用接口:
private PictureQualityGammaJni PQGammaJni;
@Override
public void onCheckedChanged(RadioGroup arg0, int arg1) {
// TODO Auto-generated method stub
switch(arg1){
case R.id.warmcolor:
Log.v(TAG,"warmcolor");
PQGammaJni.nativeSetGammaIndex(0);
break;
case R.id.normalcolor:
PQGammaJni.nativeSetGammaIndex(1);
Log.v(TAG,"normalcolor");
break;
case R.id.coldcolor:
PQGammaJni.nativeSetGammaIndex(2);
Log.v(TAG,"coldcolor");
break;
case R.id.colorfulsaturation:
Log.v(TAG,"colorfulsaturation");
PQGammaJni.nativeSetSatAdjIndex(9);
break;
case R.id.normalsaturation:
Log.v(TAG,"normalsaturation");
PQGammaJni.nativeSetSatAdjIndex(1);
break;
}
}