参考:http://www.cnblogs.com/anyanran/archive/2010/11/22/ndk1.html
http://www.cnblogs.com/sevenyuan/p/4202759.html
感谢前辈做了这么详细的记录。
下面是自己根据前辈的记录实现的。
1.创建AndroidSoTest安卓项目,包名:package com.ybs.androidsotest
2.创建类java类,JNITest 这个类是native方法,目的是为了调用c中的方法,当然c库通过ndk工具命令最后生成了.so文件。一句话简单总结native方法就是java调用非java代码的接口。
package com.ybs.androidsotest;
public class JNITest {
// Native Method就是一个java调用非java代码的接口
//这里执行了一个加法运算
public native int add(int x, int y);
}
3.AndroidSoTest项目根目录创建jni文件夹,把c库中的代码放入。创建名称为mylib.c的文件。
这里c转成了jni中的语法,关于c中类型与jni中类型的对应关系,可以参见jni的相关文档。
这里注意了:这个add方法这里有个坑,
Java_项目包名(包名各级之间都是用下划线隔开的)_方法名
#include
#include
JNIEXPORT jint JNICALL
Java_com_ybs_androidsotest_JNITest_add( JNIEnv* env,
jobject thiz,
jint x,
jint y )
{
return x + y;
}
4.AndroidSoTest项目根目录jni文件夹中,把放入的.c文件生成.h头文件,执行命令:
下面命令意思是把JNITest.java生成JNITest.h ,
把生成的JNITest.h放入jni文件夹中
//这个命令是在linux上用的(建议用此命令,在执行此命令之前,去掉此JNITest.java 类中的包名生成.h文件)
javac JNITest.java && javah JNITest
//在cmd工具,命令:
javah -jni -classpath D:\android_workspace\AndroidSoTest\src -d D:\-jni com.ybs.androidsotest.JNITest
5.这里是生成的JNITest.h文件(这里这个文件是命令生成的,非手写)
/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class JNITest */
#ifndef _Included_JNITest
#define _Included_JNITest
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: JNITest
* Method: add
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_JNITest_add
(JNIEnv *, jobject, jint, jint);
#ifdef __cplusplus
}
#endif
#endif
6.AndroidSoTest项目根目录jni文件夹中,创建Android.mk文件。Android.mk是一个makefile,用来告诉NDK需要编译哪些文件,生成哪些模块。LOCAL_PATH表示c源代码文件的位置;LOCAL_MODULE表示生成的共享库的名称;LOCAL_SRC_FILES代表c代码的文件。不需要把头文件列在里面;头文件的依赖关系是ndk自动计算的。
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := mylib
LOCAL_SRC_FILES := mylib.c
include $(BUILD_SHARED_LIBRARY)
7.AndroidSoTest项目根目录下创建Application.mk文件,Application.mk的作用是告诉Android SDK需要哪些库文件。有了它,NDK就可以把库放在正确的位置。APP_PROJECT_PATH代表android工程所在目录,在本例中它被放在中; APP_MODULES表示工程需要的库,如果有多个以空格分开。
APP_PROJECT_PATH := $(call my-dir)
APP_MODULES := mylib
8.这里要生成.so文件了,进入到项目AndroidSoTest根目录下,执行ndk-build即可。
(要windows环境上装了ndk,并且配置了环境变量。ndk下载址:https://developer.android.google.cn/ndk/downloads/index.html ,下载后解压,在系统环境变量PATH中配置环境变量,以及ndk解压后放置的目录即可。放置路径可参考: D:\androids\android-ndk-r14b-windows-x86_64\android-ndk-r14b )
命令如下:
cd AndroidSoTest
ndk-build
这时候执行完命令项目的libs文件夹中会生成armeabi文件夹,这个armeabi文件夹中会生成mylib.so文件。项目根目录下还会生成obj文件夹及相关内容。
9.这里就可以在MainActivity中调用JNITest中的方法了。代码如下:
package com.ybs.androidsotest;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends Activity {
private TextView textView;
//这里是静态加载,在生成so文件时,系统添加了lib前缀和.so后缀,这里参数就没有前缀和后缀
static{
System.loadLibrary("mylib");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView);
//这里要创建JNITest类的实例,再调用方法。
JNITest test=new JNITest();
int x = test.add(3, 5);
//显示在textView上。
textView.setText("test.add(3, 5)=="+x+"");
}
}