一直认为jni这一块技术会很麻烦,但当自己动手后发现不难,很容易上手,在Android中,官方提供了NDK这个环境,从ndk r7b 版本之后ndk包含了Cygwin,现在我理解ndk就是一个精简版的Linux环境,可以编译C/C++代码生成so文件。下面把我的实现与大家分享一下。
一 环境
1.电脑操作系统为Window7 64bit
2.NDK为:下载了android-ndk-r8d-windows.zip ,把它解压到E盘下面,解压后在路径 E:\android-ndk-r8d-windows\android-ndk-r8d 看见一系列文件,这其中包括Sample文件夹,这里面包括很多示例, 第一次使用时可以参照 hello-jni 这个示例。
解压后设置一下环境变量,把E:\android-ndk-r8d-windows\android-ndk-r8d添加到PATH里面,测试是否设置成功,进入samples\hello-jni文件夹,运行ndk-build
看见上述内容则为成功。
二 应用
1. 建立一个android项目
首先建立一个android项目AndroidJNI, 应用的包名为:com.youzhi.t.jni,创建HelloJNI.java类文件
package com.youzhi.t.jni;
public class HelloJNI {
static {
System.loadLibrary("JNITest");//so文件名
}
public static native String sayHello();
}
如图:
2. 生成h 文件
运行命令行cmd, 进入项目AndroidJNI所在的磁盘目录:E:\AndroidOSSProject\AndroidJNI,再进入 bin\classes文件夹,执行命令javah com.youzhi.t.jni.HelloJNI
会在目录classes下生成头文件com_youzhi_t_jni_HelloJNI.h
3. 在项目下面创建文件夹jni,如图
再把上一步生成的com_youzhi_t_jni_HelloJNI.h头文件剪切到jni目录下。
4. 创建c 文件
在jni目录下创建文件com_youzhi_t_jni_HelloJNI.c 文件,c文件来实现com_youzhi_t_jni_HelloJNI.h头文件定义的函数,它的内容为:
#include<jni.h>
#include<string.h>
#include<com_youzhi_t_jni_HelloJNI.h>
JNIEXPORT jstring JNICALL Java_com_youzhi_t_jni_HelloJNI_sayHello
(JNIEnv *env, jobject obj){
return(*env)->NewStringUTF(env,(char*)"Hello,JNITest");
}
它会返回字符串: Hello,JNITest
5.创建Android.mk文件
在jni目录下创建文件Android.mk文件,可以参照 samples\hello-jni 示例中的文件
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := JNITest
LOCAL_SRC_FILES := com_youzhi_t_jni_HelloJNI.c
include $(BUILD_SHARED_LIBRARY)
LOCAL_MODULE 指的是so文件的名字
LOCAL_SRC_FILES 指的是C/C++文件
6. 执行命令ndk-build
运行命令行cmd, 进入项目AndroidJNI所在的磁盘目录:E:\AndroidOSSProject\AndroidJN,执行ndk-build
命令执行后会在libs目录下生成armeabi/libJNITest.so
7. 调用
在MainActivity.java文件中
package com.youzhi.t.jni;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.widget.TextView;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tx = (TextView) findViewById(R.id.hello_tx);
tx.setText(HelloJNI.sayHello());//显示jni返回的字符串
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
运行安装项目,结果如图:
成功了!
8.支持 cpu 多种架构
另外,如果想在手机cpu 多种架构上支持,可以在Andoird.mk文件中加入
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := JNITest
LOCAL_SRC_FILES := com_youzhi_t_jni_HelloJNI.c
<span style="background-color: rgb(255, 255, 102);">##
<strong>APP_ABI := all
#x86 need android2.3 or latter
APP_ABI := armeabi armeabi-v7a x86</strong></span>
include $(BUILD_SHARED_LIBRARY)
再执行cmd命令
ndk-build APP_ABI=all