前言

现在的ndk开发已经越来越便捷,打开老电脑的AS2.0,再一次对ndk-build的编译方式有了新的认识,以前对jni、libs、jniLibs这些目录理解有点凌乱。

开发环境:

  • windows 7
  • android-ndk-r14b
  • android studio 2.0

步骤

一.local.properties添加ndk路径
ndk.dir=D\:\\download\\android-ndk-r14b

未添加则会报出下面的提示

二.gradle.properties文件,添加
android.useDeprecatedNdk=true //低版本插件

未添加则会报出下面的提示

Error:(27, 1) A problem occurred evaluating project ‘:app’.
Error: NDK integration is deprecated in the current plugin. Consider trying the new experimental plugin. For details, see http://tools.android.com/tech-docs/new-build-system/gradle-experimental. Set “android.useDeprecatedNdk=true” in gradle.properties to continue using the current NDK integration.

三.创建jni目录

新目录 src/main/jni

四.ndk-build编译
  • 自动编译 (不需要手动执行ndk-build命令)
  • 手动编译 (需要手动执行ndk-build命令)

自动编译

android studio根据ndk option自动生成Android.mk文件

在build.gradle文件中

1.指定jni目录,jni.srcDirs 是源码的位置

   sourceSets {        main {            println("---> jni默认目录 $jni")            jni.srcDirs = ['src/main/jni']            //编译 jni目录 根据defaultConfig的ndk配置自动生成mk文件  中间文件在app\build\intermediates\ndk        }    }

2.配置ndk option

  defaultConfig {        ndk {            //lib的名称,对应Android.mk文件的LOCAL_MODULE            moduleName "JniTest"            //cpu的类型            abiFilters "armeabi", "armeabi-v7a", "x86", "mips", "arm64-v8a", "x86_64", "mips64"        }    }

运行程序,生成中间文件(app\build\intermediates\ndk),这种方式编译的的so链接库会自动打包到apk的app/libs目录

手动编译
手动书写Android.mk文件,使用ndk-build命令编译

1.在build.gradle文件中,禁止自动编译ndk

   sourceSets {        main {            println("---> jni默认目录 $jni")//一旦 添加了 ndk 就会自动编译ndk  默认src/main/jni              jni.srcDirs = []//disable automatic ndk-build call 禁止自动编译 src/main/jni目录              println("---> jni新目录 $jni")        }    }

2.在jni目录下,添加Android.mk和Application.mk文件
Android.mk用于设置库文件的名称,源码路径,Application.mk文件配置编译版本

Android.mk

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := test  #库名称LOCAL_LDFLAGS := -Wl,--build-idLOCAL_SRC_FILES :=main.cpp LOCAL_C_INCLUDES += /app/src/main/jniLOCAL_C_INCLUDES += /app/src/debug/jniinclude $(BUILD_SHARED_LIBRARY)

Application.mk

#APP_PLATFORM (minimum is android-21 for 64bit support) 需要ndk11及以上版本才能编译64位#APP_ABI := armeabi  armeabi-v7a mips  x86 arm64-v8a x86_64 mips64#APP_PLATFORM := android-21 #编译版本APP_ABI := all  #编译支持的abi 对应gradle的ndk option的abiFilters

3.在项目根目录下 执行命令 ndkroot/ndkbuildCapp\src\main\jni {ndk_root}是ndk路径,如ndk是D:\download\android-ndk-r14b,则命令为

D:\download\android-ndk-r14b\ndk-build -C  app\src\main\jni

ndk-build输出的中间文件在app\src\main\libs

手动编译有利于了解GNU make的编译过程,但是需要注意将jniLibs的目录改为src/main/libs,so库才会被打包进apk中,原因是因为jniLibs.srcDir默认是src/main/jniLibs目录,然而这里并没有src/main/jniLibs目录,只有src/main/libs。。当然也可以创建src/main/jniLibs目录,拷贝so文件进去。否者运行程序将找不到so库

 jniLibs.srcDirs = ["src/main/libs"]//依赖libs目录

半手动编译
对手动编译优化,使用gradle的task 执行ndk-build
在build.gradle文件中新建task

//自带mk文件   task自动编译task buildNative(type: Exec) {    def ndkDir = android.ndkDirectory    println("---> ndk dir: ${ndkDir}")    println("---> jni file dir: ${file('src/main/jni').absolutePath}")    commandLine "$ndkDir/ndk-build.cmd",//等同于打开cmd  输入命令ndk-build.cmd -C src/main/jni            '-C', file('src/main/jni').absolutePath, // 根据jni的Android.mk生成so,在src/libs下            '-j', Runtime.runtime.availableProcessors(),//-j参数,并行执行构建命令            'all',            'NDK_DEBUG=1'}tasks.withType(JavaCompile) {    //项目编译的时候就执行buildNative任务     compileTask -> compileTask.dependsOn 'buildNative'}

备注 ndk-build的常用命令

ndk-build                   编译ndk-build -C <project路径>   指定工程的目录ndk-build clean          清掉二进制文件ndk-build NDK_DEBUG=1     编译为可调试版的二进制文件ndk-build NDK_DEBUG=0     编译为release版ndk-build NDK_LOG=1          打印出内部的NDK日志信息(用于调试NDK自己)ndk-build NDK_APP_APPLICATION_MK=<文件路径>      用这里指定的路径寻找Application.mk文件

现在的android studio早已经弃用这种自我折腾的方式了,才会有 android.useDeprecatedNdk=true这种奇葩配置。新的android studio集成ndk相对容易点了

更多相关文章

  1. Android(安卓).gitignore 忽略文件
  2. Android(安卓)读取本地图片文件和读取图片的uri
  3. linux中如何使用javah命令生成jni头文件
  4. Android(安卓)apk 反编译
  5. Android应用程序访问硬件驱动(JNI方式)
  6. 自定义 Android(安卓)Preference——SpinnerPreference的私人定
  7. 上官网学android之七(Saving Data)
  8. Android(安卓)之 Fresco 显示圆形图片 之坑
  9. Android使用FileObserver对sdcard文件或文件夹监控

随机推荐

  1. GitHub Android 开源项目汇总
  2. Android framework add service
  3. Android开发中高效的数据结构
  4. Android消息处理机制-Handler&Message概
  5. ym——android源码大放送(实战开发必备)
  6. android大图加载中的陷阱
  7. Android 基础-3.0 数据存储方式
  8. OkHttp3的基本用法
  9. Android Studio 一些使用经验---第一次使
  10. 关于含有RecyclerView的布局载入时,会滚动