android开发一段时间了,因为工作需要慢慢接触到ndk。记得第一次使用时毫无经验,各种search,各种try,两周时间才编译好一个ffmpeg的版本。这种新接触的东西就是这样,容易走弯路,搜索很多可能是过时的,或是不正确的。包括我今天想写的也不见得正确,只是因为第二次使用ndk直接把第一次的忘光了,又折腾了好久,决定把它记下来,也供大家参考,纯粹个人探索经验。(PS:由于太懒了,很多原理性的东西没有去探索,这里写下使用过程)

接触到ndk,说明要使用一点c的东西,安卓的jni调用很好的解决了这个问题。至于怎么java调c,c调java这里不多说,网上的资料很多,不会太坑。要说的是借用ndk对c进行编译的过程。

开发工具:Android studio 2.0以上版本,ndk-r11c。

一、简单操作流程
最最简单的编译过程,相信大家有所了解了。创建好项目->新建jni文件夹(src/main/jni)->在创建你的c/cpp文件->在gradle的release或者debug中添加你要编译的版本
android.ndk {
moduleName = “test”
ldLibs +=”log”
abiFilters +=”armeabi”
abiFilters +=”armeabi-v7a”
abiFilters +=”x86”
}
然后build,结果会发现若干报错,根据报错做以下几个操作:
1.给项目指定ndk位置
2.gradle.properties中添加android.useDeprecatedNdk=true
3.app gradle中添加
android {
sourceSets {
main {
jni.srcDirs = []
}
}
}

再次build,应该就哦了。
可以看看别人的操作过程:http://blog.csdn.net/u012341163/article/details/51065745

二、假如你的c代码要使用别的c代码。两种方法:拷贝所有c代码到jni、引用别的库
第一种不说,相当于自己写c,流程同上面。
第二种方法,引用别的库。我遇到的也有两种情况,别的库是个so文件,别的库提供mk文件。
1.如果是so文件,要找到它的.h头文件,将头文件和so文件同时拷贝到jni目录,此时才可以引用。当然了,因为你用了别的库文件,不可以采取上面的流程编译,因为上面的流程编译的时候会在build里生成一个临时的Android.mk文件,里面描述了你要编译打包的过程。如果你使用了别人的库,就要自己编写一个Android.mk,让ndk-build按照你的意思来。
2.在jni目录下创建编写Android.mk文件,如何编写自己搜。如果要包含so文件,可以添加如下句子
$$
include $(CLEAR_VARS)
LOCAL_MODULE := xxxx
LOCAL_SRC_FILES := libxxx.so
include $(PREBUILT_SHARED_LIBRARY)

3.因为要使用自己的Android.mk,不能使用release或者debug时指定ndk的方式编译。在app gradle中添加
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn ndkBuild
}
task ndkBuild(type:Exec,description:’生成so文件’) {
def ndkDir = android.ndkDirectory
commandLine “$ndkDir/ndk-build.cmd”,
‘NDK_PROJECT_PATH=build,
‘APP_BUILD_SCRIPT=src/main/jni/Android.mk’
}
大概意思是创建一个task叫ndkBuild,后面是这个task里面要执行的命令
4.如何执行这个task?这个不好描述,截图

点击就好了。

5.如果一切顺利就会在app/build/obj里找到你想要的东东

6.如果是有别人的库的mk文件,同样把头文件复制过来,然后将第2步改为包含其mk文件
OPENCV_CAMERA_MODULES:=on
OPENCV_INSTALL_MODULES:=on
OPENCV_LIB_TYPE:=SHARED
include D:\cd\downloads\OpenCV-3.1.0-android-sdk\OpenCV-android-sdk\sdk\native\jni\OpenCV.mk
上方三行根据它的mk规则写即可,其他步骤一致

三、在实验的过程中发现一个奇怪的问题,就是c++标准库的某些东东用不了,比如

include< iostream>

经过查资料和实验,大多数是说在jni下创建一个Application.mk文件,里面写上对c++
标准库的支持APP_STL := stlport_static即可。我试了很多次不行,最后发现是因为我的Application.mk文件压根就没生效。解决的办法在命令行那里指定要生效的Application.mk
commandLine “$ndkDir/ndk-build.cmd”,
‘NDK_PROJECT_PATH=build’,
‘NDK_APPLICATION_MK=src/main/jni/Application.mk’,
‘APP_BUILD_SCRIPT=src/main/jni/Android.mk’

今天发现另一种情况,如果加了上面这个还不行,请在app的build.gradle中加上
sourceSets.main{
jni.srcDirs = []
jniLibs.srcDir ‘src/main/libs’
}

ok,打完收工。对于我这个懒人,希望还有下次写博客的机会。

更多相关文章

  1. Android应用程序访问linux驱动第一步:实现并测试Linux驱动
  2. Framework StatusBar添加(wifi,bluetooth,gps,sound,rotate)控制面
  3. android文件选择、读取、浏览器的实现(音乐文件)
  4. Android(安卓)获取所有联系人(两种方法)
  5. gen下R文件消失 && 工程无故报错
  6. Android(安卓)开发者 for Flutter (2)如何布局? XML layout 文件跑
  7. 如何在Android平台下编译带STL的C++程序
  8. android android 在list view中插入一条广告
  9. android官方最新以及2.2、2.3.5源代码(完整)下载以及用source insi

随机推荐

  1. 闭包/访问器属性/类与对象/解构赋值/js引
  2. rest语法|剩余参数|归并参数
  3. js中的流程控制
  4. 学绘画该怎么上色?电脑绘画上色技巧!
  5. Js表单事件与数组常用 API
  6. 初识Java8中的Stream
  7. 追格积分商城小程序(开源版)源码发布下载
  8. Java中io流解析及代码实例
  9. Java实现简单订餐系统
  10. 图书管理系统java版