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 __cplusplus

extern "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.c

include $(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……)

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。