在开始之前,先介绍一下android上面的编写jni程序的一些概念。
要能够运行jni程序,首先必须出编译动态库,动态库一般是以so结尾的文件,如libhello.so。在android上面编译动态库,需要下载ndk这个交叉编译工具,具体下载地址可以到android.com这个网站去查找。ndk有windows、mac、linux版本,根据自己的需要下载,下载下来一般是一个压缩包,直接解压即可,随便放在哪个目录下都可以。我的电脑是mac,解压出来的结构如下:
编译的时候主要是用到ndk-build这个命令,为了以后方便,可以将你的ndk目录加入到环境变量中,这样就不用每次都输入一长串的路径了。
以我的mac电脑为例,打开用户目录下的.bash_profile文件,输入
NDK=/Users/hejinlai/Android/android-ndk-r8c
export NDK
这样以后就可以直接用$NDK这个变量了,而不用每次都敲/Users/hejinlai/Android/android-ndk-r8c
windows上面需要下载cygwin来模拟linux环境,具体的设置可以参考网上的资料。
还有,我的ndk版本是r8,可能每个人下载的ndk版本不一样,在使用的时候可能会有所差别,具体查看ndk的文档。
下面就正式来编写一个hello jni:调用c程序返回的一个字符串Hello Jni,然后在手机上显示出来
1、先新建一个android工程,这个不需要多说,搞android开发的人都应该知道的
2、在android工程的跟目录下,新建一个jni目录,然后在这个目录下编写c文件和makefile文件
hello_jni.c
#include <jni.h>
#include <string.h>
jstring Java_com_example_hellojni_MainActivity_hello(JNIEnv *env, jobject jobj)
{
return (*env)->NewStringUTF(env, "Hello, JNI");
}
jni函数的命名有很多规则,这里暂时不讨论,以后会慢慢研究。
c文件写完后,开始编写makefile文件,makefile文件命名必须是Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello
LOCAL_SRC_FILES := hello_jni.c
include $(BUILD_SHARED_LIBRARY)
然后执行ndk-build进行编译:
编译完成后,会在android工程下面生成libs目录,so文件就在这个libs目录下面:
到这里,jni的工作算是完成了,下面就是java中调用了
主要是声明native方法和加载刚才生成的so库:
package com.example.hellojni;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.widget.TextView;
public class MainActivity extends Activity {
TextView textView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.hello_tx);
textView.setText(hello());
}
private native String hello();
static{
System.loadLibrary("hello");
}
}
具体细节稍后介绍,最后就可以运行了:
可以看到Hello,JNI输出到手机上了。