Android平台NDK编程
转自:http://blog.csdn.net/wangbin_jxust/article/details/37389383
之前在进行cocos2dx开发时,已经详细介绍了如何将win32的c++代码移植到Android平台,当再次回顾时,发现一些基础的东西理解并不是很彻底,今天使用Android NDK提供的一个例子做一个简单的移植。在进行该demo前,请确认你已经配置了Android开发环境和安装了最新的Android NDK。
1.创建Android项目
创建一个Android项目 , 包名是com.example.hellojni,创建一个Activity作为程序进入的Acitivity,命名为HelloJni。
2.创建 C 文件
创建一个C文件,放一个函数,该函数的作用是获取当前cpu架构并以字符串的形式返回。请注意该函数的格式: Java_包名的下划线连接_Java文件名_java函数名。
#include <string.h>
#include <jni.h> jstring
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
jobject thiz )
{
#if defined(__arm__)
#if defined(__ARM_ARCH_7A__)
#if defined(__ARM_NEON__)
#define ABI "armeabi-v7a/NEON"
#else
#define ABI "armeabi-v7a"
#endif
#else
#define ABI "armeabi"
#endif
#elif defined(__i386__)
#define ABI "x86"
#elif defined(__mips__)
#define ABI "mips"
#else
#define ABI "unknown"
#endif return (*env)->NewStringUTF(env, "Hello from JNI ! Compiled with ABI " ABI ".");
}
3.配置JNI
在该Android项目的根目录(即AndroidManifest.xml文件所在目录)下创建一个文件夹,命名为jni(注意,文件名不能写错哦)
在jni目录下,创建Android.mk和Application.mk两个文件,同时将C文件也放进jni文件夹下面来。如下:

这里的nick文件夹,可以先忽略不看,这是为后面的打包多个so准备的。
a.配置Android.mk文件
Android.mk文件实际上一个很小的NDK构建脚本,它的语法在: NDK安装目录/docs/ANDROID-MK.html,下文代码也对一些基本属性添加了注释。
#返回当前文件在系统中的路径,mk文件开始时必须定义该变量
LOCAL_PATH := $(call my-dir) #CLEAR_VARS 变量由构建系统提供,因为有大量的全局变量,在本次构建前,清除上一次的
include $(CLEAR_VARS)
#LOCAL_MODULE 实际是项目名,用于区分各个项目,名字必须是唯一的而且不包含空格,最终的so库,命名也会是 lib项目名.so
LOCAL_MODULE := hello-jni
#要编译的c or cpp文件,注意不需要在这里列举头文件或者include的文件,构建系统会自动帮你依赖这些文件
LOCAL_SRC_FILES := hello-jni.c
#构建系统提供的变量
include $(BUILD_SHARED_LIBRARY)
b.配置Application.mk文件
Application.mk文件实际上是对应用程序本身描述的文件,它定义了应用程序需要的功能模块的列表、针对不同cpu架构打包不同的so]、要构建release或者debug包等。
APP_ABI := XXX,这里的XXX就是指不同的平台,可以选填的有x86,armeabi,armeabi-v7a,mips,all,值得一提的是,选择all,则会构建出所有平台的so,如果不填该项,默认构建为armeabi的。同时,作者也做过一个实验,构建armeabi平台的so是可以运行在intel x86架构cpu平台的,但是构建x86平台的so则不能在armeabi平台上运行的,这样看来,应该是intel针对armeabi做了兼容,但是如果想要so 以最小的能耗运行在intel x86平台,还是要指定构建的so为x86平台。
4.打包so以及如何打包多个so
在当前Android项目的根目录下,运行 NDK安装路径/ndk-build,则开始打包so。
另外,如果运行 NDK安装路径/ndk-build clean,会clean当前所有的so;
运行 NDK安装路径/ndk-build -B V=1,则强制重新打包,
如果想要打包多个so,则可以在Android.mk定义多个modules,或者写多个Android.mk,每个Android.mk定义一个modules,我这里在jni目录下又创建了一个nick文件夹,用于放置新的C文件。

此时,只需要改动jni目录下的Android.mk,再次对nick文件夹的C代码打包即可。jni下的Android.mk文件:
#返回当前文件在系统中的路径,mk文件开始时必须定义该变量
LOCAL_PATH := $(call my-dir) #CLEAR_VARS 变量由构建系统提供,因为有大量的全局变量,在本次构建前,清除上一次的
include $(CLEAR_VARS)
#LOCAL_MODULE 实际是项目名,用于区分各个项目,名字必须是唯一的而且不包含空格,最终的so库,命名也会是 lib项目名.so
LOCAL_MODULE := hello-jni
#要编译的c or cpp文件,注意不需要在这里列举头文件或者include的文件,构建系统会自动帮你依赖这些文件
LOCAL_SRC_FILES := hello-jni.c
#构建系统提供的变量
include $(BUILD_SHARED_LIBRARY) #对nick文件夹下的代码打包so
include $(CLEAR_VARS)
LOCAL_MODULE := hello-jni-mine
LOCAL_SRC_FILES := nick/hello-jni.c
include $(BUILD_SHARED_LIBRARY)
是的,你没看错,重新加上LOCAL_MODULE和LOCAL_SRC_FILES变量重新配置一下即可。
5.jni调用
在Activity中,我们使用static 关键词将加载so放在函数体中,以保证直接先加载so.
static {
System.loadLibrary("hello-jni");
}
要注意的是,System.loadLibrary()中填写的并不是完整的so名,而是去掉前缀lib和后缀.so的,也就是Android.mk中的LOCAL_MODULE变量。
java层的函数要用native关键词声明这次调用native层的函数,如果该java函数是public native String XXXX(),那么在这里就是调用C代码中的Java_com_example_hellojni_HelloJni_stringFromJNI()函数。
以上就是Android平台打包so和调用的一个最基本的demo,其实整个流程还是比较简单的,有一些规定的命名是不能随便修改的,如果jni文件夹名,Android.mk,Application.mk文件名,被java层调用的C函数命名等,这些都是有规则的。
Android平台NDK编程的更多相关文章
- 两分钟学会Android平台NDK编程(无须Eclipse和cygwin,可使用命令行打包多个so)
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/wangbin_jxust/article/details/37389383 之前在进行cocos2d ...
- Android Studio NDK编程初探
继上一篇学习了如何使用NDK编译FFMPEG后,接下来就是要学习如何在Android Studio中使用了. 经过参考和一系列的摸索,记录下具体步骤. 创建C++ Support的Android St ...
- Android JNI&NDK编程小结及建议
前言 由于网上关于JNI/NDK相关的知识点介绍的比较零散而且不具备参照性,所以写了这篇JNI/NDK笔记,便于作为随时查阅的工具类型的文章,本文主要的介绍了在平时项目中常用的命令.JNI数据类型.签 ...
- Android之NDK编程(JNI)
转自:http://www.cnblogs.com/xw022/archive/2011/08/18/2144621.html NDK编程入门--C回调JAVA方法 一.主要流程 1. 新建一个 ...
- android平台蓝牙编程
Android平台支持蓝牙网络协议栈,实现蓝牙设备之间数据的无线传输. 本文档描述了怎样利用android平台提供的蓝牙API去实现蓝牙设备之间的通信,蓝牙设备之间的通信主要包括了四个步骤:设置蓝牙设 ...
- android平台蓝牙编程(转)
http://blog.csdn.net/pwei007/article/details/6015907 Android平台支持蓝牙网络协议栈,实现蓝牙设备之间数据的无线传输. 本文档描述了怎样利用a ...
- Android Studio Ndk 编程
如今开发Android程序基本都已经从Eclipse转到了Android Studio了, 近期项目需求, 须要用到ndk编程, 于是就折腾了一下. 开发环境 Android Studio 1.5.1 ...
- Android Studio NDK编程-环境搭建及Hello!
一,下载 安装android-ndk开发包 NDK各个版本链接二,新建项目NDKDemo,选择空Activity就可以:(注:Android studio 2.2,可通过SDK Tools 添加LLD ...
- Android Studio NDK编程-环境搭建及Hello!
一,下载 安装android-ndk开发包 NDK各个版本链接二,新建项目NDKDemo,选择空Activity就可以:(注:Android studio 2.2,可通过SDK Tools 添加LLD ...
随机推荐
- 字符串string
1.字符串获取类.封装检测数字的方法 var str = '前端开发'; //alert(str.length); //alert(str.charAt()); //没有参数 取得索引是0 结果是:前 ...
- rtree
https://zh.wikipedia.org/wiki/R%E6%A0%91 http://blog.csdn.net/jiqiren007/article/details/5377750 htt ...
- jdbc操作数据库返回结果集的注意事项
import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sq ...
- Yii入门,登录
验证和授权在页面需要限制访问时用到.验证就是确认某人就是他所声称的那个人.通常涉及到用户名和密码,但也包含其他方式,例如智能卡,指纹等.授权是在验证用户后,查明他是否被允许管理指定的资源.通常判断他是 ...
- YII 快速创建项目GII
Yii 是一个基于组件.纯OOP的.用于开发大型 Web 应用的高性能PHP框架. 它将Web编程中的可重用性发挥到极致,能够显著加速开发进程 .Yii适合大流量的应用,如门户.BBS.CMS及B2B ...
- go 应用程序性能测试
runtime/pprof 我们要加入对pprof包里的方法调用,程序才能将运行时候程序的堆内存分配状态记录到文件(也可以是写到其他地方,例如网络等)中,以便进一步的分析. 如果你的go程序只是一个应 ...
- Fisher information matrix笔记
在看FK论文时,fisher information matrix是必须理解的. 从维基百科查阅到,Fisher information matrix是用利用最大似然函数估计来计算方差矩阵. 来源于: ...
- 高级正则表达式技术(Python版)
正则表达式是从信息中搜索特定的模式的一把瑞士军刀.它们是一个巨大的工具库,其中的一些功能经常被忽视或未被充分利用.今天我将向你们展示一些正则表达式的高级用法. 举个例子,这是一个我们可能用来检测电话美 ...
- 记录一下ORACLE 10gR2的软件下载地址,备用。
转载自:http://www.eygle.com/archives/2008/06/10gr2_download_link.html 记录一下ORACLE 10gR2的软件下载地址,备用. 下载OTN ...
- 使用nodejs中httpProxy代理时候出现404异常
在公司中使用nodejs构建代理服务器实现前后台分离,代码不能拿出来,然后出现httpProxy代理资源的时候老是出现404.明明被代理的接口是存在的.代码大概如下: var http = requi ...