注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

民主与科学

独立之人格,自由之思想

 
 
 

日志

 
 

JNI应用程序开发  

2010-08-27 16:32:35|  分类: 开发专题 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
android的JNI开发一种是内核级的(android源码),一种是一般的应用程序(它被打入到APK包)。在此讨论的是一般的应用程序。
开发JNI应用需要的工具有
Android NDK
下载地址:
http://developer.android.com/sdk/ndk/index.html#requirements
而要运行Android NDK的命令(比如ndk-build)需要
    *  For all development platforms, GNU Make 3.81 or later is required. Earlier versions of GNU Make might work but have not been tested
    * A recent version of 
awk (either GNU Awk or Nawk) is also required.
    * For 
WindowsCygwin 1.7 or higher is required. The NDK will not work with Cygwin 1.5 installations.
以上信息来自于http://developer.android.com/sdk/ndk/index.html#requirements.
注意Android的这个文档有点误导人
对于Linux平台需要GNU Make 3.81 or later,或A recent version of awk (either GNU Awk or Nawk)。
虽然对于Windows也需要GNU Make 3.81 or later,或A recent version of awk (either GNU Awk or Nawk)。
但是实际上如果对
Cygwin 1.7 or higher是完全安装的话Cygwin 就已经包含了GNU Make和awk的window版本
因此Window平台下,其实对Cygwin进行完全安装就行了
在http://developer.android.com/sdk/ndk/index.html#requirements还有很多有用信息,可以参阅。

GNU Make下载地址
linux版本
http://ftp.gnu.org/gnu/make/
awk下载地址:
linux版本
http://linux.softpedia.com/get/Text-Editing-Processing/Filters/GNU-awk-207.shtml
window版本
http://www.softpedia.com/get/CD-DVD-Tools/CD-DVD-Images-Utils/Gawk-for-Windows.shtml
gawk下载地址:
http://ftp.gnu.org/gnu/gawk/
Cygwin下载地址
http://www.cygwin.com/
关于Cygwin安装步骤请参阅《cygwin安装详解
注意Cygwin的安装包选项那屏,点击包菜单根的"All"后面的"Default",然它变成"install",就是完全安装。
在安装Android NDK后:
在其samples目录下找到很多实例程序
在其docs目录下可以看到有很多帮助文档,
    首先阅读的应该是OVERVIEW.TXT。
    关于Android.mk文件的编写在ANDROID-MK.TXT中
    关于Application.mk文件的编写在APPLICATION-MK.TXT中
    关于Android NDK的安装要求在INSTALL.TXT中。

如何在Eclipse中进行android的JNI开发。
1,首先需要在Eclipse建个Android工程
    工程名为JniHello,Activity名为HelloActivity
2,HelloActivity中载入一个JNI包
    在使用JNI的接口前,需要载入JIN的包。
    我这里的JIN包名为hello-jni
    (其文件名为lib+包名+.so,即libhello-jni.so)。
    HelloActivity中载入如下:
        static {
            System.loadLibrary("hello-jni");
        }

 3,在Java声明一个JNI函数
 native String getStringFromJni();
 4,在Java中使用JIN函数和一般的java函数一样
     public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        TextView textView=(TextView)findViewById(R.id.textView1);
        textView.setText(
getStringFromJni());
    }

 5,建立jni源代码的目录jni.
 在JniHello下建立个jni目录。
6,在头文件中声明C\C++的Jni函数
如果你需要不同的JNI的C\C++实现文件的函数能互相调用,那么你就需要为你的JNI的C\C++端编写扩展名为h的头文件。
你可以手写头文件,也可以使用javah命令。
关于javah命令的详细内容请参考《javah命令详解
这里我不需要不同的JNI的C\C++实现文件的函数进行调用,因此略去该步骤。
 7,定义Jni函数
 在目录jni下新建个文件hello-jni.c如下:
    #include <string.h>
    #include <jni.h>
   
 jstring
    Java_com_teleca_robin_HelloActivity_getStringFromJni( JNIEnv* env,
                                                      jobject thiz )
    {
        return (*env)->NewStringUTF(env, "Hello robin,this world is from JNI !");
    }

函数返回类型
jstring代表的是返回类型。这里应该表示的是java的String.
函数名字
函数名字首先是前缀java,然后是要调用该JNI的Java类的路径,
接着是Java中申明的函数的名字
函数参数
第一个参数永远应该是JNIEnv* env,
第二个参数jobject thiz是java中的this指针。
第三个参数开始是Java的函数中的参数。

比如实例bitmap-plasma中的Plasma对renderPlasma声明如下:
 private static native void renderPlasma(Bitmap  bitmap, long time_ms);
 在jni中则为
 JNIEXPORT void JNICALL Java_com_example_plasma_PlasmaView_renderPlasma(JNIEnv * env, jobject  obj, jobject bitmap,  jlong  time_ms)
关于JNI中参数的传递与操作的更多内容请参考《JNI中参数的传递与操作
注意:JNIEXPORT和JNICALL都是JNI的关键字,表示此函数是要被JNI调用的
应用层级的Java类别通过VM而调用到本地函数,VM默认是按照JNI的java函数和C\C++本地函数的命名规范,去寻找*.so里的本地函数。
查找的过程还是有点耗时。如果调用次数很多,而每次都寻找一遍的话,会花掉许多时间。
如果你想节约VM查找JNI本地函数的时间,你可以通过registerNativeMethods()函数把JNI本地函数向VM进行登记,以节约VM查找JNI本地函数的时间。
如果你的JNI本地函数的命名没严格遵守java函数和C\C++本地函数对应的命名规范,你必须通过registerNativeMethods()函数把JNI本地函数向VM进行登记,以便VM能找到你的JNI本地函数。
关于JNI本地函数向VM进行登记,请参照《JNI系统程序开发
 8,编辑Android.mk
 在jni下新建Android.mk文件如下:
 LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE    := hello-jni
LOCAL_SRC_FILES := hello-jni.c
include $(BUILD_SHARED_LIBRARY)。
关于Android.mk的更多内容请参照《Android.mk
9,编译JNI
在cygwin\home\hubin的.bash_profile文件中添加设置ndk的路径。
NDK=/cygdrive/d/SDK/android-ndk-r4b
export NDK 。
programs->Cygwin->Cygwin Bash Shell或直接点击cygwin\Cygwin.bat打开cygwin bash shell窗口,
然后进入工程JniHello的根目录
执行$NDK/ndk-build。
这时应该就能在JniHello的根目录的libs\armeabi下生成libhello-jni.so。
注意:在cygwin中进入一个盘符的命令为cd D:的形式
关于Cygwin的使用的更多内容请参阅《Cygwin使用指南
10,在Ecplise中重新打包生成apk文件,libhello-jni.so也同时被打进了apk.
11,像运行一般android程序一样运行该程序
在jni函数中向android的控制台打印信息可以采用以下的方式。
#include <android/log.h>
#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
LOGI("frame/s (avg,min,max) = (%.1f,%.1f,%.1f) "
     "render time ms (avg,min,max) = (%.1f,%.1f,%.1f)\n",
     1000./avgFrame, 1000./maxFrame, 1000./minFrame,
     avgRender, minRender, maxRender);

关于如何定义多个JNI包(module),请参考android-ndk-r4b\samples\two-libs
关于jni的使用可以参照《JNI应用程序开发实例1
  评论这张
 
阅读(1644)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017