Chinaunix首页 | 论坛 | 博客
  • 博客访问: 851360
  • 博文数量: 143
  • 博客积分: 455
  • 博客等级: 一等列兵
  • 技术积分: 861
  • 用 户 组: 普通用户
  • 注册时间: 2012-08-03 00:11
文章分类

全部博文(143)

文章存档

2018年(10)

2017年(6)

2016年(28)

2015年(14)

2014年(67)

2013年(1)

2012年(17)

我的朋友

分类: Android平台

2014-08-21 15:58:43

(1)JNI工程建立

        在Android目录下任意创建一个目录jnidemo,并在该目录下创建三个文件:Android.mk,用于编译JNI工程的makefile文件;jnidemo.cpp,JNI代码文件;onload.cpp,用于注册JNI方法的文件。

[html] view plaincopy在CODE上查看代码片派生到我的代码片
  1. mkdir jnidemo  
  2. cd jnidemo  
  3. touch Android.mk  
  4. touch jnidemo.cpp  
  5. touch onload.cpp  

(2)编辑jnidemo.cpp

  1. #include "JNIHelp.h"  
  2. #include "jni.h"  
  3. #define LOG_TAG "Service-JNI"  
  4.   
  5. namespace android  
  6. {  
  7.     static jint nativeOpen(JNIEnv* env,jobject obj){  
  8.             ALOGE("JNI test nativeOpen");  
  9.             return 10;  
  10.     }  
  11.   
  12.     static JNINativeMethod method_table[] = {  
  13.             {"nativeOpen","()I",(void*)nativeOpen }  
  14.     };  
  15.   
  16.     int register_android_jnidemo_Service(JNIEnv *env){  
  17.             return jniRegisterNativeMethods(env,"com/example/test/Demo",  
  18.               method_table,NELEM(method_table));  
  19.     }  
  20. };  

这里我们提供了一个接口给Java层调用,即nativeOpen()。定义register_android_jnidemo_Service()方法,用于注册JNI文件,在该方法中,用到了两个关键的参数。一个是"com/example/test/Demo",对应着java代码的包名和类名,即调用JNI的java代码所在的包是“com.example.test”,类名是Demo;另一个是method_table,即是上面初始化的JNINativeMethod结构体。
(3)编辑onload.cpp

  1. #include "JNIHelp.h"  
  2. #include "jni.h"  
  3. #include "utils/Log.h"  
  4. #include "utils/misc.h"  
  5.   
  6. namespace android {  
  7.     int register_android_jnidemo_Service(JNIEnv* env);  
  8. };  
  9.   
  10. using namespace android;  
  11. extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)  
  12. {  
  13.     JNIEnv* env = NULL;  
  14.     jint result = -1;  
  15.   
  16.     if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {  
  17.         ALOGE("GetEnv failed!");  
  18.         return result;  
  19.     }  
  20.     ALOG_ASSERT(env, "Could not retrieve the env!");  
  21.   
  22.     register_android_jnidemo_Service(env);  
  23.     return JNI_VERSION_1_4;  
  24. }  

当java代码调用System.loadLibrary()加载JNI库的时候,将调用到onload.cpp的JNI_OnLoad()方法,然后将调用在jnidemo.cpp文件中定义的方法register_android_jnidemo_Service(env)对JNI进行注册。其实很简单吧,onload.cpp就是完成注册功能的。

(4)编辑Android.mk

[html] view plaincopy在CODE上查看代码片派生到我的代码片
  1. LOCAL_PATH:= $(call my-dir)  
  2. include $(CLEAR_VARS)  
  3.   
  4. LOCAL_MODULE_TAGS :eng  
  5. LOCAL_SRC_FILES:= \  
  6.     jnidemo.cpp \  
  7.     onload.cpp  
  8.   
  9. LOCAL_SHARED_LIBRARIES := \  
  10.      libnativehelper \  
  11.      liblog  
  12.   
  13. LOCAL_MODULE:libjnidemo  
  14. 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内容:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. package com.example.test;  
  2.   
  3. import android.util.Log;  
  4.   
  5. public class Demo {  
  6.     String TAG="Demo";  
  7.     static {  
  8.        System.loadLibrary("jnidemo");  
  9.     }  
  10.   
  11.     public native int nativeOpen(); //以native 申明JNI函数  
  12.     public Demo(){  
  13.        Log.v(TAG,"get from jni = "+nativeOpen());  
  14.     }  
  15. }  

activiy的内容

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. package com.example.test;  
  2.   
  3. import android.os.Bundle;  
  4. import android.app.Activity;  
  5.   
  6. public class MainActivity extends Activity {  
  7.    
  8.     @Override  
  9.     protected void onCreate(Bundle savedInstanceState) {  
  10.         super.onCreate(savedInstanceState);  
  11.         setContentView(R.layout.activity_main);  
  12.         new Demo();                 
  13.     }  
  14. }  

运行时就会在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

阅读(1027) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~