Android NDK JNI实现案例

如果读者和我一样也是没有Linux基础、NDK、Android懂点但是想写Android调用C++代码的话这篇文章很适合你。

准本工作:

   1.NDK(到百度网盘搜索即可)我用的是android-ndk32-r10b-windows-x86

   2.安卓平台是:andriod_budle_ADT\adt-bundle-windows-x86_安卓开发带eclipse版   API:17

有以上两个即可完成Android平台下调用C++代码。

对于NDK的操作是:

 

    1.在Eclipse上添加NDK的地址。

       按照图上所标记做即可。

   


2.让你的Eclipse在添加之后识别C/C++代码的操作:如图

点击add之后的弹出add directory path 填写路径

D:\android_studio\android-ndk32-r10b-windows-x86\toolchains\mipsel-linux-android-4.6\prebuilt\windows\lib\gcc\mipsel-linux-android\4.6\include

点击OK继续add,路径为

D:\android_studio\android-ndk32-r10b-windows-x86\platforms\android-17\arch-arm\usr\include

继续add 路径为$Android_NDK_HOME/platforms/android-17/arch-arm/usr/include

第二个路径和第三个路径注意与你自己的API保持一致。你API若是14则应将17修改为14。硬盘的路径根据自己的NDK解压路径来写即可,但是到了NDK路径下是一致的。

这步操作是让你的Eclipse在自己实现的C、C++代码不报错。稍后会提到这一点。

3.添加系统环境变量,还是说一下吧:

变量名我的是NDK_ROOT,变量值是:第一步中的NDK location的值

对于path的修改是:添加%NDK_ROOT%;(注意后又分号)

下面是对于Android的操作:

1、在src下创建一个java类

2.进入DOS环境(快捷键ctr+r)

在DOS环境下,使用javah命令在你的工程目录下的classes文件夹内生成对应的头文件

我的路径是:F:\android\MyJniTest\bin\classes 对应输入代码如图:


在该路径下的文件并不会在我们自己的安卓IDE的工程目录结构中含有,我们可以自己建立一个JNI文件夹,将该文件复制到该文件夹下。

我们打开该.h文件,其中已经生成了JNI方法,最好不要动,如果都能理解那就随便改。在此时如果发现你的JNI的宏定义比如:JNIEXPORT jint JNICAL   有了BUG的标识符出现,你检查一下你的NDK的操作是否都有了。

3.接下来进入.cpp文件的实现:

  JNI文件夹下new一个com_example_myjnitest_TestJni.cpp文件(我是直接复制com_example_myjnitest_TestJni.h,重命名,删除com_example_myjnitest_TestJni.h文件内容)也可以是一个file命名改下后缀为.CPP即可。
下面是关于如何实现com_example_myjnitest_TestJni.cpp文件:
我认为关注一下几点:
1>.包含头文件:
包含C/C++的进本输入输出的库函数,
包含进我们在DOS环境使用javah生成的头文件,即com_example_myjnitest_TestJni.h
包含我们自己在使用Eclipse手动创建的头文件
2>JNI函数的实现:
注意函数名的命名方式与java中的方法命名的方式不同(可以从com_example_myjnitest_TestJni.h头文件复制该函数名,函数命名一定要注意建议直接复制)
注意指针的使用

4.用Eclipse自带的C++创建一个C++程序,包含.h和.cpp文件。

先有一步设置:选中项目-->右键单击-->选中Android Tools-->选中add Native support 这步是必须有的

生成的.h文件Add.h并添加代码注意我此处是删除其构造函数和析构函数

#ifndef ADD_H_
#define ADD_H_
class Add {
public:

  int add(int x,int y);
};

#endif /* ADD_H_ */

生成.cpp文件并添加代码,:

#include "Add.h"
int Add::add(int x, int y) {
    return x + y;
}

 5.new两个.mk文件,就是new两个file文件命名时后缀是.mk即可

   

注意如图的目录结构,Android.mk是在JNI目录下,Application.mk是在工程目录下的。

Android.mk内容如下:

LOCAL_PATH := $(call my-dir) 
include $(CLEAR_VARS)  


LOCAL_MODULE := MyJniTest  ----这是你在MainActivity类中动态加载的库文件的名称,我用的是与工程名相同,
  
LOCAL_SRC_FILES := com_example_myjnitest_TestJni.cpp  ----这是你自己new的.cpp文件
LOCAL_SRC_FILES += Add.cpp  ---这是自己实现的c++代码对应Eclipse new的C++类的cpp文件
  
include $(BUILD_SHARED_LIBRARY)  

除了我标注的三行代码外的代码都不可修改,也就是标注的三行代码是可以修改的。

如图我们点击add native support 后平台的操作是:

Application.mk中的代码:

APP_PROJECT_PATH := $(call my-dir)  
APP_MODULES := MyJniTest ---是与你的Android.mk中的LOCAL_MODULE := MyJniTest 相对应的

6.再次进入DOS环境下,将路径设置到包含Application.mk文件目录下,设置到我们当前工程目录下即可:

输入代码:F:\android\MyJniTest>ndk-build(这是我的)好到此,你可以刷新并查看你的Android的IDE目录结构已经发生了改变。是否成功关注:

下图所示内容:


至此我们再对MainActivity.java中添加相关的测试代码即可:

static {
// 加载动态库
System.loadLibrary("MyJniTest");
}//这段代码是必须有的,加载动态链接库,注意就是加载的我们生成.so文件

这期间出现的错误:

1.Android NDK: WARNING: APP_PLATFORM android-17 is larger than android:minSdkVersion 8 in      ./AndroidManifest.xml

make.exe: *** No rule to make target `jni/com_example_myjnitest_TestJni.cpp', needed by `obj/local/armeabi/objs/MyJniTest/com_example_m
yjnitest_TestJni.o'.  Stop.

2.

原因:我在之前排错时找不到错误就乱改将我原先写的.cpp文件改为了.c文件致使找不到.cpp文件,

修改的方法是:检查你的Android.mk得LOCAL_SRC_FILES := 值是不是与你new的.cpp文件 

Android NDK: WARNING: APP_PLATFORM android-17 is larger than android:minSdkVersion 8 in ./AndroidManifest.xml
make.exe: *** No rule to make target `D:/android_studio/android-ndk32-r10b-windows-x86/sources/cxx-stl/system/com_example_myjnitest_TestJni.cpp', needed by `obj/local/armeabi/objs/MyJniTest/com_example_myjnitest_TestJni.o'.  Stop.

原因是:在Android.mk文件中的LOCAL_PATH := $(call my-dir) 前多写了个L

修改:去掉一个就行了,当然要说的不是这,而是读者遇到可能不是那么低级,但是指明的方向,可能是这块其他的错误,比如有的网友就说是LOCAL_PATH := $(call my-dir)_  这样修改或者其后应当有空格,

代码下载地址:http://download.csdn.net/detail/u013793732/9296801




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值