(1)JNI工程建立
在Android目录下任意创建一个目录jnidemo,并在该目录下创建三个文件:Android.mk,用于编译JNI工程的makefile文件;jnidemo.cpp,JNI代码文件;onload.cpp,用于注册JNI方法的文件。
-
mkdir jnidemo
-
cd jnidemo
-
touch Android.mk
-
touch jnidemo.cpp
-
touch onload.cpp
(2)编辑jnidemo.cpp
-
#include "JNIHelp.h"
-
#include "jni.h"
-
#define LOG_TAG "Service-JNI"
-
-
namespace android
-
{
-
static jint nativeOpen(JNIEnv* env,jobject obj){
-
ALOGE("JNI test nativeOpen");
-
return 10;
-
}
-
-
static JNINativeMethod method_table[] = {
-
{"nativeOpen","()I",(void*)nativeOpen }
-
};
-
-
int register_android_jnidemo_Service(JNIEnv *env){
-
return jniRegisterNativeMethods(env,"com/example/test/Demo",
-
method_table,NELEM(method_table));
-
}
-
};
这里我们提供了一个接口给Java层调用,即nativeOpen()。定义register_android_jnidemo_Service()方法,用于注册JNI文件,在该方法中,用到了两个关键的参数。一个是"com/example/test/Demo",对应着java代码的包名和类名,即调用JNI的java代码所在的包是“com.example.test”,类名是Demo;另一个是method_table,即是上面初始化的JNINativeMethod结构体。
(3)编辑onload.cpp
-
#include "JNIHelp.h"
-
#include "jni.h"
-
#include "utils/Log.h"
-
#include "utils/misc.h"
-
-
namespace android {
-
int register_android_jnidemo_Service(JNIEnv* env);
-
};
-
-
using namespace android;
-
extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)
-
{
-
JNIEnv* env = NULL;
-
jint result = -1;
-
-
if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
-
ALOGE("GetEnv failed!");
-
return result;
-
}
-
ALOG_ASSERT(env, "Could not retrieve the env!");
-
-
register_android_jnidemo_Service(env);
-
return JNI_VERSION_1_4;
-
}
当java代码调用System.loadLibrary()加载JNI库的时候,将调用到onload.cpp的JNI_OnLoad()方法,然后将调用在jnidemo.cpp文件中定义的方法register_android_jnidemo_Service(env)对JNI进行注册。其实很简单吧,onload.cpp就是完成注册功能的。
(4)编辑Android.mk
-
LOCAL_PATH:= $(call my-dir)
-
include $(CLEAR_VARS)
-
-
LOCAL_MODULE_TAGS := eng
-
LOCAL_SRC_FILES:= \
-
jnidemo.cpp \
-
onload.cpp
-
-
LOCAL_SHARED_LIBRARIES := \
-
libnativehelper \
-
liblog
-
-
LOCAL_MODULE:= libjnidemo
-
include $(BUILD_SHARED_LIBRARY)
LOCAL_SHARED_LIBRARIES 用到的共享库,libnativehelper是用于注册JNI用到的共享库,liblog是用于打印log用到的共享库,即ALOGD()方法需要的。 LOCAL_MODULE 编译输出模块的名称,编译之后将生成libjnidemo.so文件
在完成以上工作后,在jnidemo目录下执行mm命令,之后将在out产品目录下的system/lib/目录下生成libjnidemo.so文件,将该文件push到目标板的/system/lib目录下。
(5)制作一个简单的apk,新建一个Demo类,在activity的onCreate函数中完成new Demo实例,就可以了。Demo.java内容:
-
package com.example.test;
-
-
import android.util.Log;
-
-
public class Demo {
-
String TAG="Demo";
-
static {
-
System.loadLibrary("jnidemo");
-
}
-
-
public native int nativeOpen();
-
public Demo(){
-
Log.v(TAG,"get from jni = "+nativeOpen());
-
}
-
}
activiy的内容
-
package com.example.test;
-
-
import android.os.Bundle;
-
import android.app.Activity;
-
-
public class MainActivity extends Activity {
-
-
@Override
-
protected void onCreate(Bundle savedInstanceState) {
-
super.onCreate(savedInstanceState);
-
setContentView(R.layout.activity_main);
-
new Demo();
-
}
-
}
运行时就会在eclipse的Logcat中发现如下log:
01-03 00:23:56.693: E/Service-JNI(2709): JNI test nativeOpen
01-03 00:23:56.693: V/Demo(2709): get from jni = 10
第一条是在JNI的nativeOpen方法中打印的,第二条是在Java代码中打印的。看到这个结果,说明JNI 已经ok了。
参考原文:http://blog.sina.com.cn/s/blog_89f592f501013ge3.html
阅读(1021) | 评论(0) | 转发(0) |