转载请注明出处:http://www.cnblogs.com/fpzeng/p/4281801.html

源码请见 https://github.com/fpzeng/HelloJNI

PC系统: ubuntu 12.04

Android SDK: android-sdk-linux_r24

Android NDK:android-ndk-r10d

概述

在android上使用ndk的步骤:

  1. 创建java文件,声明native方法;
  2. 使用javah生成C语言接受的头文件*.h;
  3. 创建*.c文件,使用C语言实现该native方法;
  4. 编译*.c文件产生so库
  5. 运行的时候,java使用System.loadLibrary打开so库,调用native方法。

声明native方法

在com.fpzeng.example.jni.HellojniActivity声明native方法:

private native String nativeGetMacAddress(int Parameter1);

此时目录结构如下: 

AndroidManifest.xml
-jni
Android.mk
-src
   hello_jni.c
-src
  -com
  -fpzeng
  -example
  -jni
  HellojniActivity.java
-res ...

产生头文件

使用javah产生jni头文件,会将产生的头文件com_fpzeng_example_jni_HellojniActivity.h输出到jni目录下。命令如下:

javah -jni -d jni -classpath src/ com.fpzeng.example.jni.HellojniActivity

产生的 com_fpzeng_example_jni_HellojniActivity.h头文件如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_fpzeng_example_jni_HellojniActivity */ #ifndef _Included_com_fpzeng_example_jni_HellojniActivity
#define _Included_com_fpzeng_example_jni_HellojniActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_fpzeng_example_jni_HellojniActivity
* Method: nativeGetMacAddress
* Signature: (I)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_fpzeng_example_jni_HellojniActivity_nativeGetMacAddress
(JNIEnv *, jobject, jint); #ifdef __cplusplus
}
#endif
#endif

此时的入参数是int,返回值类型时String类型。  

引入Android SDK

如果将java中声明的native方法变的复杂,比如引入Context。在com.fpzeng.example.jni.HellojniActivity声明native方法更新为

private native String nativeGetMacAddress(Context context);

  运行产生命令: javah -jni -d jni -classpath src/ com.fpzeng.example.jni.HellojniActivity,此时提示错误:

Error: Cannot determine signature for Context

这是由于javah不认识Context类,需要将android.jar包含进来才行。

我的LINUX环境变量中,使用ANDROID_SDK_ROOT指向了当前android-sdk-linux_r24的绝对路径,大家也需要设置自己的ANDROID SDK环境变量。此时,头文件的生成命令如下:

javah -jni -d jni -classpath src/:$ANDROID_SDK_ROOT/platforms/android-15/android.jar com.fpzeng.example.jni.HellojniActivity

产生的 com_fpzeng_example_jni_HellojniActivity.h头文件如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_fpzeng_example_jni_HellojniActivity */ #ifndef _Included_com_fpzeng_example_jni_HellojniActivity
#define _Included_com_fpzeng_example_jni_HellojniActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_fpzeng_example_jni_HellojniActivity
* Method: nativeGetMacAddress
* Signature: (Landroid/content/Context;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_fpzeng_example_jni_HellojniActivity_nativeGetMacAddress
(JNIEnv *, jobject, jobject);
#ifdef __cplusplus
}
#endif
#endif

加入Android.mk  

每次新加native方法都需要运行该命令,是不是很头痛?

首先在jni/Application.mk中指定当前的工程路径,用变量APP_PROJECT_PATH指向。

APP_PROJECT_PATH := $(shell pwd)
APP_CFLAGS+=-Wno-error=format-security
APP_PLATFORM := android-15
APP_ABI := armeabi-v7a
APP_OPTIM := debug

然后在jni/Android.mk 加入响应的参数依赖,如下:

headers:
$(warning app project path $(APP_PROJECT_PATH))
@cd $(APP_PROJECT_PATH)
javah -jni -d jni -classpath src/:$ANDROID_SDK_ROOT/platforms/android-15/android.jar com.fpzeng.example.jni.HellojniActivity

此时运行ndk-build headers,首先打印 aap project path目录,然后进入该目录执行javah命令。

Android ndk第一步,构建jni headers的更多相关文章

  1. JDK 安装与环境配置配置——Android开发第一步

    什么是JDK? JDK 即 Java Development Kit,Java开发工具包,用来编译 Java 程序.JRE 在接触JDK的过程中,同时了解到 JRE,JRE 即 Java Runtim ...

  2. NDK plugin来构建JNI项目(相对于手动构建)

    http://blog.csdn.net/codezjx/article/details/8879670 1.添加ndk环境支持 Android Tools -> Add Native Supp ...

  3. Android NDK(一) ndk-build构建工具进行NDK开发

    本文目录 一.androidstudio环境 二.快捷键配置 三.新建项目 四.NDK开发 五.so文件编译 一. androidstudio的环境 在SDK Tools中安装NDK开发环境(File ...

  4. Android NDK(二) CMake构建工具进行NDK开发

    本文目录 一Androidstudio中需要的插件 二项目配置 ①build.gardle配置 ②CMakeLists.txt ③Android和Cpp的代码 ④so文件生成 ⑤so文件的位置 一.A ...

  5. android 学习第一步

    今天是2015年7月24号,今年下半年的主要学习方向是android,学习的目标是做出3个或以上的有实用价值的app.

  6. [原]Android 开发第一步

    使用 android-studio 开发 写文章时的最新 Android-Studio 程序下载:https://dl.google.com/dl/android/studio/ide-zips/3. ...

  7. android ndk之hello world

    前言:Android NDK r7及以上的版本已经集成了Cygwin编译环境,也就是说,我们完全可以抛弃庞大的Cygwin了. r6及以下版本,也可以抛弃几个G的完整版,使用精简过的Mini-Cygw ...

  8. Android NDK编程浅入深出之--Android.mk

        Android.mk Android.mk是一个向Android NDK构建系统描写叙述NDK项目的GUN Makefile片段.它是每个NDK项目的必备组件. 构建系统希望它出如今jni子文 ...

  9. Docker多步构建更小的Java镜像

    译者按: 最新版Docker将支持多步构建(Multi-stage build),这样使用单个Dockerfile就可以定义多个中间镜像用于构建,测试以及发布等多个步骤,并且有效减小最终镜像的大小. ...

随机推荐

  1. 总结:man, info, hwclock, cal, type, which, dirname, basename, who, which, whatis, makewhatis, hash, tty

    man, info, help, date, hwclock, cal, shutdown, reboot, halt, poweroff, type, cd, which, dirname, bas ...

  2. BZOJ3412: [Usaco2009 Dec]Music Notes乐谱

    3412: [Usaco2009 Dec]Music Notes乐谱 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 35  Solved: 30[Sub ...

  3. SDL2.0 学习笔记-1 windows下的第一个测试程序

    SDL全称是Simple DirectMedia Layer,是一个开源的.跨平台(win32,linux,mac)的多媒体开发c语言库. 官方网站 http://www.libsdl.org/ 第一 ...

  4. linux内存管理子系统

    一.Linux内存管理模型 1.虚拟地址与物理地址的映射 2.物理地址的分配二.虚拟地址与物理地址的映射 1.虚拟地址空间分布 32位处理器有32根地址总线,可访问4G的物理空间.其中有0-3G为用户 ...

  5. HDU_2051——十进制到二进制转换

    Problem Description Give you a number on base ten,you should output it on base two.(0 < n < 10 ...

  6. Java编程思想-第四章练习题

    练习1:写一个程序,打印从1到100的值 public class Print1To100{ public static void main(String args[]){ for(int i = 1 ...

  7. OSI七层以及各层上的协议

    各层简介: [1]物理层:主要定义物理设备标准,如网线的接口类型.光纤的接口类型.各种传输介质的传输速率等.它的主要作用是传输比特流(就是由1.0转化为电流强弱来进行传输,到达目的地后在转化为1.0, ...

  8. java.lang.String小测试

    还记得java.lang.String么,如果现在给你一个小程序,你能说出它的结果么 public static String ab(String a){ return a + "b&quo ...

  9. Android-自定义PopupWindow

    PopupWindow在应用中应该是随处可见的,很常用到,比如在旧版本的微信当中就用到下拉的PopupWindow,那是自定义的.新版微信5.2的ActionBar,有人已经模仿了它,但微信具体是使用 ...

  10. debian linux 中如何查看软件包是否已经安装和如何安装、卸载软件

    练习 1 方案:确定软件包是否安装 如果您不确定某个软件包是否已经安装,可以使用 dpkg 的 -l (L的小写) 选项: $ dpkg -l zsh No packages found matchi ...