首页 > 代码库 > Linux下通过NDK的初步使用

Linux下通过NDK的初步使用

参考资料:

1、版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明

http://eshock.blogbus.com/logs/61459223.html

2、http://www.cnblogs.com/anyanran/archive/2010/11/22/ndk1.html

 

1、平台及软件信息

通过 uname -a 查看: 

Linux ubuntu 3.13.0-35-generic #62-Ubuntu SMP Fri Aug 15 01:58:01 UTC 2014 i686 i686 i686 GNU/Linux

为了确认各环境变量配置正确,可以通过:

 java -version 查看:

java version "1.7.0_67"Java(TM) SE Runtime Environment (build 1.7.0_67-b01)Java HotSpot(TM) Client VM (build 24.65-b04, mixed mode)

ndk-build 查看:

Android NDK: Could not find application project directory !    Android NDK: Please define the NDK_PROJECT_PATH variable to point to it.    /home/anna/Downloads/android-ndk-r10b/build/core/build-local.mk:148: *** Android NDK:Aborting    .  Stop.

同时在eclipse中安装好ADT和CDT插件,能正常运行java写的应用程序。

2、编写java代码

  新建Android工程,包名设置为”com.anna”,类名为JniTest,在其中实现native方法plus和sayHello,分别用于传回字符串和数字给java。代码如下:

package com.anna;import android.os.Bundle;import android.support.v7.app.ActionBarActivity;public class JniTest  extends ActionBarActivity {   public native String sayHello();  public native int plus(int x,int y);  @Override  protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_jni_test);    int x = plus(3,2);    System.out.println("The result in java is: "+x);    //将返回的字符串设置为app的title    this.setTitle(""+this.sayHello());  }    static{    System.loadLibrary("mylib");  }}

3、生成com_anna_JniTest.h头文件

  实现native方法需要用javah命令生成相应的头文件,使用头文件中对native方法定义的形式来在C/C++语言中实现,而当前的java代码尚不能使用javac命令正确编译,因此提取出仅包含native方法的Java文件,进行编译获得相关信息。

public class JniTest{  public native String sayHello();  public native int plus(int x,int y);}
使用 javah -jni JniTest 命令生成JniTest.h文件
/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class JniTest */ #ifndef _Included_JniTest#define _Included_JniTest#ifdef __cplusplusextern "C" {#endif/* * Class:     JniTest * Method:    sayHello * Signature: ()Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_JniTest_sayHello  (JNIEnv *, jobject); /* * Class:     JniTest * Method:    plus * Signature: (II)I */JNIEXPORT jint JNICALL Java_JniTest_plus  (JNIEnv *, jobject, jint, jint); #ifdef __cplusplus}#endif#endif

  其中的两个JNIEXPORT句就是所需要的native方法描述,切记要在函数名之前添加包名,即Java_JniTest_sayHello ——> Java_com_anna_JniTest_sayHello

4、编写.c文件

  在路径下新建名为jni的文件夹,在其中新建mylib.c(根据System.loadLibrary("mylib");命名),内容为:

#include <string.h>#include <jni.h>JNIEXPORT jint JNICALL Java_com_anna_JniTest_plus(JNIEnv *env, jobject obj, jint x, jint y){  return x+y;}JNIEXPORT jstring JNICALL Java_com_anna_JniTest_sayHello(JNIEnv *env,  jobject obj)
{   
return (*env)->NewStringUTF(env, "Hello from JNI ! ");}

  在其中实现了int型和String类型数据的返回,C和java中数据类型并不完全对应,因此使用jint、jstring样式的命名方式方便编程。

5、编写Android.mk和Application.mk文件

  在jni文件夹下新建文件Android.mk,内容如下:

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE    := mylib LOCAL_SRC_FILES := mylib.cinclude $(BUILD_SHARED_LIBRARY)

  其中LOCAL_MODULE表示要生成的动态链接库.so文件的文件名(所生成的文件会自动添加lib头,即本次生成的so文件名为”libmylib.so”),LOCAL_SRC_FILES表示c文件的所在路径。

  在项目总目录下(即与src目录等同级)新建文件Application.mk,内容如下:

APP_PROJECT_PATH := $(call my-dir)APP_MODULES      := mylib

  其中的APP_MODULES与LOCAL_SRC_FILES的内容相同。

6、生成libmylib.so文件

  切换命令行工具到jni目录下,使用 -ls  命令查看,文件夹内包含:

 Android.mk   mylib.c

  之后使用 ndk-build 命令,运行后命令行输出如下:

[armeabi] Install        : libmylib.so => libs/armeabi/libmylib.so

  根据输出可知,输出的so文件存放在整个项目的ibs/armeabi/路径下,如果没有的话,右键工程”refresh”一下就出现啦。

7、运行工程,查看输出结果

  LogCat中输出结果为:

  模拟器界面输出为:

  

  (注:Hello World是工程默认建立的TextView……)

Linux下通过NDK的初步使用