Android NDK学习笔记
前言
Android系统中的应用程序都是用Java开发的。Android NDK使我们能够在android上使用C/C++开发的原生代码。有两个理由使用NDK: 一是合理的重用现有的代码;二是在程序中某些关键的部分提高执行效率。
这里先讲几个符号的约定:
<project> - 你的Android应用程序工程的目录
<ndk> - 你的ndk安装的目录
捷径
这里先扯一句题外话 -- 如果你不需要使用NDK开发,只是需要使用第三方用NDK开发的库,那么你只需要这样做:
把第三方提供的libxxx.so放到你的<project>/libs/armeabi/下, 然后在程序随便什么地方中加入
static {
System.loadLibray("xxx");
}
就可以使用该库了。
安装NDK
NDK的安装很简单:
1. 首先要将SDK升级至最新,然后下载ndk(可能要,恩恩)将它解压到某个目录<ndk>下。
2. 运行: <ndk>/build/host-setup.sh
3. 如果成功的话就OK了,如果失败的话检查一下你是不是下载了正确的ndk版本(例如你的操作系统是linux而下载了windows版的ndk).
Java部分
现在我们用一个很简单的例子来说明NDK的使用。我们在eclipse中新建一个android工程,其中:
Project Name:jnitest
Build Target: Android 1.6
Application Name: JNI Test
Package Name: org.eshock.jnitest
Create Activity: JNITest
JNITest.java:
package org.eshock.jnitest;
import android.app.Activity;
import android.os.Bundle;
public class JNITest extends Activity {
public native int plus (int x, int y);
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
int x = plus(1, 2);
android.util.Log.d("jni", String.valueOf(x));
}
static {
System.loadLibrary("mylib");
}
}
我们只是演示NDK,所以就不要界面了。在这个程序中,我们调用一个c语言编写的plus(int, int)函数来计算1+2的值,然后在log中打印它。这个库的名称叫做mylib。
要使用一个c语言的函数,需要在java中声明:
public native int plus(int x, int y);
这样java编译器就知道这个函数是外部库中实现的。
C部分
接下来我们使用C语言实现这个plus函数。
创建<project>/jni/mylib.c:
#include <string.h>
#include <jni.h>
JNIEXPORT jint JNICALL
Java_org_eshock_jnitest_JNITest_plus( JNIEnv* env,
jobject thiz,
jint x,
jint y )
{
return x + y;
}
这 里我们看到,mylib.c里的plus函数比java里面的plus函数的签名要复杂了很多,主要是plus前面增加了包名,函数中多了两个参数,以及 所有的int变成了jint。关于c中类型与jni中类型的对应关系,可以参见jni的相关文档,例如core Java II中的最后一章。如果你不想去查阅文档,有一个方法:
首先随便在某个目录下创建一个文件JNITest.java:
public class JNITest {
public native int plus (int x, int y);
}
然后在命令行下执行:
javac JNITest.java && javah 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: plus
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_JNITest_plus
(JNIEnv *, jobject, jint, jint);
#ifdef __cplusplus
}
#endif
#endif
这里自动生成了java中native函数对应的签名,你可以在c代码中使用它。(记得修改包名)。
Android.mk和Application.mk
Android.mk是一个makefile,用来告诉NDK需要编译哪些文件,生成哪些模块。我们创建<jni>/Android.mk文件:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := mylib
LOCAL_SRC_FILES := mylib.c
include $(BUILD_SHARED_LIBRARY)
其中LOCAL_PATH表示c源代码文件的位置;LOCAL_MODULE表示生成的共享库的名称;LOCAL_SRC_FILES代表c代码的文件。不需要把头文件列在里面;头文件的依赖关系是ndk自动计算的。
Application.mk的作用是告诉Android SDK需要哪些库文件。有了它,NDK就可以把库放在正确的位置。我们创建<project>/Application.mk:
APP_PROJECT_PATH := $(call my-dir)
APP_MODULES := mylib
APP_PROJECT_PATH代表android工程所在目录,在本例中它被放在<project>中; APP_MODULES表示工程需要的库,如果有多个以空格分开。
编译共享库
由于ndk规定Application.mk必须放在<ndk>/apps/project_name,我们在<ndk>下创建一个符号连接:
ln -s <project> <ndk>/apps/jnitest
这样,我们就可以开始编译共享库了:
在<ndk>目录下运行:
make APP=jnitest
Android NDK: Building for application 'jnitest'
Compile thumb : mylib <= apps/jnitest/jni/mylib.c
SharedLibrary : libmylib.so
Install : libmylib.so => apps/jnitest/libs/armeabi
可以看到编译成功,并在<project>/libs/armeabi/下生成了libmylib.so。
测试
在运行之前,首先确认一下你的工程里面各个文件都齐全,应该类似于这样:
然后测试,正常的话应该能看到log中有输出3.
相关推荐
android studio中使用ndk编译.so文件,调用C/C++代码(jni编程)
NDK编译 JAVA JNI 原生调用,需要的下载吧,
教你如何生成.h文件,使用window通过NDK编译出.so文件,如何通过JNI调用so文件
在android中可以用这个程序了解整个,什么事ndk,jni,理解他们之间的关系
android配置ndk,使用swig编译生成jni Java接口调用c++方法。这是成功的例子,前提是你要配置一下你的环境变量。如有疑问,可以去查看我的博客。有相关内容。
基于老罗的《Android内核源代码情景分析》第二章freg实例,使用NDK编译jni层从而调用驱动程序,能大大缩短项目开发周期。
1.) 在项目根目录下创建jni目录,下面是要放进去的第一个文件Android.mk LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := main_jni #LOCAL_CFLAGS := LOCAL_SRC_FILES := main.cpp #LOCAL_...
Android 用ndk+jni编译C++文件代码,实现crc16加密数据,给Android调用
用ndk r9编译的ffmpeg2.2.4库,可以在android中通过jni方法调用, 头文件请自己到官网下载源代码
Android NDK编程,我的第一个hello-jni程序,如何调用自己编译的so库 博客地址:http://blog.csdn.net/dqksky/article/details/40425977
Android Studio两个工程中:一个使用jni可以编译成so,一个app中加载so,调用jni的接口
自己在android studio 环境下集成ndk 、 cmake 、LLDB 等插件 开发的一个demo ; 可以直接debug到c端代码,eclipse一般追踪不到,遇到c端出问题手机直接一个crash,,,想要了解android studio 下如何进行c 开发的...
基于NDK TOOL的动态库实现,包含JNI调用、动态库的编译。 1、编译本地调用的JAVA类 2、使用javah从JAVA类中转换成相应的头文件(已有genHeader.bat的脚本直接生成,其中的com.ex.sot.NativeDataManage是相应的类,需...
本人修改为安卓NDK编译程序,并扩展了,安卓调用接口,包括了检测,对齐,识别,在同一个程序中,附全部源码,含C源码,jni接口,安卓调用,可跟据你的需要随意加接口,首次运行会将几个老师的bin文件自动复制到本地...
用ndk编译c代码,并用jni调用函数,实现android与c++或者c的通信。
人脸检测,检测人睁闭眼睛,可以判断是否疲劳驾驶,代码是androidStudio+opencv工程,并且带android下JNI通过NDK编译so库文件的功能。。
windows下eclipse集成cygwin编译android_NDK(即结合jni调用c-c++).doc
安卓视频转换中一些耗时操作可以采用调用C++so库的方式进行,则需要ndk编译了,Android JNI 函数注册。从NDK下载到jni编写,ndk编译,C++文件编写,安卓demo运行
1.使用NDK来生成so文件: hello-jni.c 函数名Java +包名+函数名字 2.修改Android.mk文件 ... 您可能感兴趣的文章:android开发实践之ndk编译命令简单示例Android NDK开发简单程序分享(Hello Word!
Android JNI 调用 Silk 音频编解码包,采用现在Skepe官网上最新的1.09版修改为成,可以使用Cygwin编译即可产生.so文件,供大家使用