JNI小程序:Java通过JNI调用C程序

        JNI是Java Native Interface的缩写,中文为JAVA本地调用。使用JNI可以很方便的用我们的Java程序调用C/C++程序。很多时候,某些功能用Java无法实现,比如说涉及到底层驱动的一些功能,这时候我们就可以利用JNI来调用C或者C++程序来实现,这就是JNI的强大之处。但是JNI也有它的缺点,使用java与本地已编译的代码交互,通常会丧失平台可移植性。

1、首先配置SDK环境,配置NDK环境、配置JDK环境;这些环境的搭建这里我就不做过多介绍

2、编写Android小程序,这里我简单放一个Button按钮,目的就是调用底层C语言传过来的值;这里我只粘贴关键代码。这个是在onCreate()函数里面设置点击按钮后的事件。

                btnGetC = (Button) findViewById(R.id.btnGetC);
		btnGetC.setOnClickListener(new OnClickListener(){
			@Override
			public void onClick(View v) {
				Toast.makeText(MainActivity.this, "单击成功"+show(), Toast.LENGTH_SHORT).show();  
			}
		});

定义native函数,为了调用C语言里面的值。这里只对其进行定义。

/**
	 * 该方法为native方法 ,获取C语言的代码
	 * @return
	 */
	public static native String show();
3、加载so文件

/**
	 * 载入JNI生成so库文件
	 */
	static{
		System.loadLibrary("libJNI");
	}
加载的libJNI要和lib下面的so文件名一致;如lib下面的so文件名为libHookFun.so,那么这里放的参数应该为HookFun

4、在工程文件下创建jni目录,新建c程序文件为hello.c文件。引入头文件#include<jni.h>。下面是hello.c文件中的代码;

JNIEnv* env = NULL;

extern "C" {JNIEXPORT <span style="color:#FF0000;"><strong>jstring </strong></span>JNICALL <strong><span style="color:#FF0000;">show</span></strong>(<strong><span style="color:#FF0000;">JNIEnv *env,jclass tis</span></strong>) //jstring要和native函数中的返回值照应,show为native函数名;其中默认两个参数,如果有其他参数可以继续添加
	{

		return NULL;//这里我返回了空,这里你可以添加自己的C程序,最后返回的时候要转化为jstring类型,具体可以参考JNI的编写规则;
	}
}
static JNINativeMethod getMethods[] =
{
	{"<strong><span style="color:#FF0000;">show</span></strong>", "<span style="color:#FF0000;"><strong>()Ljava/lang/String;</strong></span>", <strong><span style="color:#FF0000;">(void*)show</span></strong>}//第一个参数为函数名,第二个参数括号内为参数类型,括号外为返回类型,第三个为函数指针类型;
};

static int registerNativeMethods(JNIEnv* env, const char* className, JNINativeMethod* gMethods, int numMethods)//这个是注册函数,固定的,可以参考此;下面固定;
{
	jclass clazz;
//	clazz = env->FindClass(className);
	jclass temp = env->FindClass(className);
	clazz =(jclass)env->NewGlobalRef(temp);

	if (clazz == NULL)
	{
		return 0;
	}
	if (env->RegisterNatives(clazz, gMethods, numMethods) < 0)
	{
		return 0;
	}
	return 1;
}

static int registerNatives(JNIEnv* env)
{
	if (!registerNativeMethods(env, "com/example/jnihook/MainActivity", getMethods, sizeof(getMethods) / sizeof(getMethods[0])))
		return JNI_FALSE;

	return JNI_TRUE;
}

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void *reserved)
{
//	LOGI("before antiDebug");
//	antiDebug(true);
//	LOGI("after antiDebug");


	jint result = -1;
	if(vm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK)
		return -1;

	if(!registerNatives(env))
		return -1;

	return JNI_VERSION_1_4;
}
5、在jni目录下编写Android.mk文件,这个是配置文件,具体可以参考网上http://blog.csdn.net/ly131420/article/details/9619269文章有介绍

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)


LOCAL_MODULE  := <strong><span style="color:#FF0000;">JNIHook</span></strong>
LOCAL_LDLIBS	:= -llog
LOCAL_LDLIBS	+= -landroid
LOCAL_CFLAGS	:= -fpermissive -DDEBUG -O0 -fexceptions
LOCAL_CFLAGS	+= -I~/android-4.4/system/core/include

LOCAL_SRC_FILES := \
hello.cpp
		
include $(BUILD_SHARED_LIBRARY)
这里Local_module模块为lib加载的so文件名,local_src_files下面为C程序的文件。

6、配置C程序的编译器,这个和ndk的路径有关

具体可以参考下面我的截图


配置好之后就可以自动的进行编译;

完成好之后就可以运行了,点击按钮会弹出“单机成功NULL”。表示JNI程序运行通过测试。

具体复杂的,还要了解JNI的编写规则,mk文件的编写,C和Java程序的编写等等。


  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

互联网极客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值