手把手教你NDK入门篇

NDK全称是native develop tools,用来交叉编译C/C++代码生成so动态链接库文件。交叉编译指的是在一个平台编译出另一个平台可以执行的代码。比如在操作系统为window、CPU架构为X86的平台编译出可以在操作系统为linux、cpu架构为arm的平台上执行的代码。

一、需要的工具
  • ndk r9:这里我用的是android-ndk-r9,当然可以去下载更新版本的。下载后解压,配置环境变量。
    配置环境变量图
  • cdt:eclipse需要集成此插件。当然也可以直接去下载已经集成了cdt插件的eclipse。
    cdt下载地址:cdt下载地址
  • eclipse/android studio
二、用eclipse写第一个例子

这里我们写第一个例子,这个例子很简单,就是用C写一句话,java层调用。写这个例子时,eclipse并没有配置ndk路径。只是把ndk下载解压配置了环境变量。因为我们要手写。

  • 在类中写一个本地方法(这里我是在MainActivity中)
private native String helloFromC();
  • 在项目中创建jni目录,在jni目录下创建hello.c文件
  • 在hello.c里面写代码了…
#include <jni.h>
// 注意方法命名为:Java_包名_类名_方法名, 必须要有如下两个参数
jsting Java_com_example_ndkdemo_MainActivity_helloFromC(JNIEnv* env,jobject thiz ){
 // 把C中的字符串转换为JAVA中的字符串
 return (*env)->NewStringUTF(env, "hello fromc..");
}

这里值得注意的是,包名指的是android工程的包名,类名指的是刚才我们写的那个本地方法所在类的类名,方法名要跟我们那个本地方法名一样。参数一:jni环境,二级指针。参数二:本地方法所在类对象。

  • 在jni目录下新建Android.mk配置文件,添加如下代码,根据具体情况修改库名、源文件名。
LOCAL_PATH := $(call my-dir)
    include $(CLEAR_VARS)  
    LOCAL_MODULE    := hello    # 编译出来的库的名称
    LOCAL_SRC_FILES := Hello.c  # 要编译的源文件
    include $(BUILD_SHARED_LIBRARY)
  • 在jni目录下新建Application.mk配置文件,目的是生成各CPU架构的so文件,不然可能会跟手机cpu架构不匹配而运行不成功。
APP_ABI := armeabi armeabi-v7a x86
  • 打开命令行窗口,进行编译。首先进入该项目jni目录,然后用ndk-build.cmd编译。
    用命令编译
  • 在类中加载本地so库
static{
    System.loadLibrary("hello");
}
  • 可以使用了,我们这里是显示到一个TextView中,运行项目,效果如下:
    效果图
三、使用集成环境写第二个例子

经过一系列繁琐的步骤,终于完成了艰难的NDK第一个例子,但是以我们上面那个步骤,明显有点复杂,因为很多文件都是我们手动创建出来的,而且C中的方法也是我们自己写,但是它的定义有点麻烦,什么Java_包名_类名…..如果能工具生成的话,是不是很爽….当然,这肯定是可以实现的….

  • 指定ndk路径
    ndk路径
  • 在类中书写本地方法
private native String helloFromC();
private native int add(int x,int y);
  • 自动生成jni和Android.mk配置文件,但是Application.mk不会自动生成,自己添加一下吧….
Android项目右键 --> Android tools --> add native support...
  • 生成c文件中的方法
    打开cmd命令窗口,进入项目src目录,用javah命令生成java类中native方法对象的jni方法。用法是:javah 包名.类名,如果中文乱码,可以加上-encoding utf-8。 然后在src会生成一个文件,把里面方法复制到jni目录下.c文件里就好了,不过方法参数好像没有变量,自己填上,书写方法体即可。
    这里写图片描述
#include <jni.h>

JNIEXPORT jstring JNICALL Java_com_example_ndkdemo2_MainActivity_helloFromC
  (JNIEnv * env, jobject obj){
     return (*env)->NewStringUTF(env, "hello from c..");
}

JNIEXPORT jint JNICALL Java_com_example_ndkdemo2_MainActivity_add
  (JNIEnv * env, jobject obj, jint i, jint j){
    return i+j;
}
  • 关联头文件,解决报错问题
Android ndk项目右键 --> properties --> c/c++ general(需要安装了cdt才能看到此项) --> 
paths and symbols --> includes 页中点击 add --> file system 再选择路径(这个路径是你解压的android-ndk-r9的下面\platforms\android-18\arch-x86\usr\include的路径,参考如下):
F:\Android_Tools\android_ndk_r9\android-ndk-r9\platforms\android-18\arch-x86\usr\include
  • 在类中使用吧
static{
    System.loadLibrary("gxh");//so名字按具体情况修改
}
setContentView(R.layout.activity_main);
TextView tv01=(TextView) findViewById(R.id.tv_01);
tv01.setText(helloFromC()+"-------"+add(3,7));
  • 运行项目吧,骚年,运行的时候会自动生成so包的。。。
    效果图
四、用Android Studio进行NDK开发

上面写了那么多,都是在eclipse里,下面介绍下在Android Studio中的用法,废话不多说,上步骤!!!慢着!!!还是有话要说的…今天在Android Studio中新建项目写例子时,报了两个错误,以我蹩脚的英文水平没看明白,百度了半天也没什么资料参考….最后偶然看到某网站一段视频说如果编译版本过高的话,相应的NDK版本也要升高。猛然醒悟,我的编译版本是23,而NDK版本是r9,于是一气之下去网上下载了最新的r14b….不过好像r10应该就可以了。。。大家注意更新一下NDK版本吧。。ps:浪费这么多时间,已哭晕在厕所…

  • 新建工程,配置ndk路径
    配置ndk路径
  • 生成.class文件
Build-->Make Projet

这里写图片描述

  • 书写native方法,这里我还是在MainActivity中
static {
    System.loadLibrary("hello");//so库
}
public native String helloFromC();
  • 用 javah命令生成jni目录以及.h文件(其实想得到C函数)
    打开Terminal,默认已经进入该项目的目录了,但是我们要进入java目录,命令如下,其中第二行命令-d ../jni表示在本目录的上一级(也就是main目录)新建jni目录。执行完命令后,main/jni下会生成.h文件
    javah命令

  • 在jni下写.c源文件
    在jni目录下新建hello.c文件,把.h文件中的方法复制过来修改,删除.h文件。网传说是不能只有一个.c文件,,于是我又添加了一个空的.c文件。至于一个.c文件行不行,没有测试。

#include <jni.h>
JNIEXPORT jstring JNICALL Java_cn_gxh_ndkdemo_MainActivity_helloFromC(JNIEnv * env, jobject obj){
      return (*env)->NewStringUTF(env, "hello from c..,this is android studio");
}
  • 配置build.gradle(module下的)
    这里写图片描述
    moduleName 后面的值是要生成的so库名,要跟那个 System.loadLibrary(“hello”);这里对应起来啊。abiFilters表示要生成哪些cpu架构平台的so包。

  • gradle.properties中添加代码,表示允许使用过时的ndk版本

android.useDeprecatedNdk=true
  • Make Project一下,可以看到生成了so库,然后可以运行了。
    这里写图片描述
    这里写图片描述

到这里,这篇NDK入门篇终于写完了。。如有错误,欢迎指正。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值