作者 : 韩曙亮 


最近在移植一个 JNI 项目, 比较纠结, Android Studio 中 NDK 到底怎么配置啊...  Android 官方的示例总是不稳定, 这两个月都改变了好几次了, Gradle 插件之前支持的后来也不支持了, 遇到各种问题, 最后还是用命令行编译, 然后将 so 库导入到 Android Studio 项目中;




1. NDK 开发遇到的问题



NDK 开发遇到的问题​ : 

-- ​之前使用的 Gradle 插件版本​ : classpath 'com.android.tools.build:gradle:2.2.0-alpha4' ;

-- ​之前使用的 Gradle 版本​ : distributionUrl=https\://services.gradle.org/distributions/gradle-2.14-all.zip;

-- ​这个版本使用 ndk 使用的配置是​ : 在 Moudle 中的 build.gradle 中 的 android 中的 defaultConfig 中 如下配置, 即可编译 jni 代码;


externalNativeBuild{
ndkBuild{
path 'src/main/jni/Android.mk'
}
}



-- ​插件版本低错误​ : 昨天用的好好的, 今天打开居然编译不通过, 应该是更新了最新的 Android Studio 导致的, 报出如下错误 : 


Error:(1, 0) Plugin is too old, please update to a more recent version, or set ANDROID_DAILY_OVERRIDE environment variable to "dad44248ed636c3b2fa21c7dea26e2d05b0d650b"


-- ​错误原因​ : 经过检查发现是 gradle 插件 和 工具 版本太低, 查询最新的工具版本;

-- ​查询 Gradle 插件最新版本​ : 查询地址 ​​https://jcenter.bintray.com/com/android/tools/build/gradle/​​, 经查询 最新版本是 2.2.0-alpha6;

-- ​查询 Gradle 工具最新版本​ : 查询地址 ​​http://services.gradle.org/distributions​​​​, 最新版本是 gradle-2.14.1-all.zip;

-- ​gradle-wrapper.properties 配置​ : 


distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip


-- ​Gradle 插件配置​ : 


buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.0-alpha6'
//classpath 'com.android.tools.build:gradle:2.1.0'

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}



-- ​插件不支持​ : 居然不支持 ndk path 设置 Android.mk 了, 居然不支持了 ... 无语了;


Gradle sync failed: Could not find method path() for arguments [src/main/jni/Android.mk] on object of type com.android.build.gradle.internal.dsl.ExternalNativeNdkBuildOptions.
Consult IDE log for more details (Help | Show Log)


--

其它问题​ : 不仅如此, C 项目的代码跳转 查看 功能也不能使用了, 代码也不让好好看了, 不稳定版本各种问题;





2. 暂时方案 Android 工程直接使用 命令行编译好的 so 库




暂时的方案 : 

-- 使用命令行 ndk-build 生成 so 库, 然后 Android 项目中直接使用 so 库;

-- 编译项目 : 进入 c 语言项目, 直接使用 ndk-build 编译, 确保你的 Android.mk 是正确的;


bogon:jni octopus$ ndk-build 
[armeabi] Compile thumb : fluidsynth-android <= fluid_adriver.c
[armeabi] Compile thumb : fluidsynth-android <= fluid_dll.c
[armeabi] Compile thumb : fluidsynth-android <= fluid_list.c
[armeabi] Compile thumb : fluidsynth-android <= fluid_seq.c
[armeabi] Compile thumb : fluidsynth-android <= fluid_mdriver.c
[armeabi] Compile thumb : fluidsynth-android <= fluid_seqbind.c
[armeabi] Compile thumb : fluidsynth-android <= fluid_aufile.c
[armeabi] Compile thumb : fluidsynth-android <= fluid_cmd.c
[armeabi] Compile thumb : fluidsynth-android <= fluid_dsp_float.c
[armeabi] Compile thumb : fluidsynth-android <= fluid_midi.c
[armeabi] Compile thumb : fluidsynth-android <= fluid_settings.c
[armeabi] Compile thumb : fluidsynth-android <= fluid_chan.c
[armeabi] Compile thumb : fluidsynth-android <= fluid_midi_router.c
[armeabi] Compile thumb : fluidsynth-android <= fluid_sndmgr.c
[armeabi] Compile thumb : fluidsynth-android <= fluid_chorus.c
[armeabi] Compile thumb : fluidsynth-android <= fluid_event.c
[armeabi] Compile thumb : fluidsynth-android <= fluid_synth.c
[armeabi] Compile thumb : fluidsynth-android <= fluid_gen.c
[armeabi] Compile thumb : fluidsynth-android <= fluid_mod.c
[armeabi] Compile thumb : fluidsynth-android <= fluid_sys.c
[armeabi] Compile thumb : fluidsynth-android <= fluid_conv.c
[armeabi] Compile thumb : fluidsynth-android <= fluid_hash.c
[armeabi] Compile thumb : fluidsynth-android <= fluid_tuning.c
[armeabi] Compile thumb : fluidsynth-android <= fluid_voice.c
[armeabi] Compile thumb : fluidsynth-android <= fluid_io.c
[armeabi] Compile thumb : fluidsynth-android <= fluid_dart.c
[armeabi] Compile thumb : fluidsynth-android <= fluid_ramsfont.c
[armeabi] Compile thumb : fluidsynth-android <= fluid_defsfont.c
[armeabi] Compile thumb : fluidsynth-android <= fluid_rev.c
[armeabi] Compile thumb : fluidsynth-android <= main.c
[armeabi] SharedLibrary : libfluidsynth-android.so
[armeabi] Install : libfluidsynth-android.so => libs/armeabi/libfluidsynth-android.so


Android Studio NDK 代码 Source Insight调试 (NDK 目前开发方案 | NDK 编译 | 导入 so 库 | 项目编码转换)_ico

-- 拷贝 so 库到 Android 项目中 : 在 src/main 目录下创建 jniLibs 目录, 将 ndk 编译后的 armeabi 目录拷贝到该目录, 运行正确;

Android Studio NDK 代码 Source Insight调试 (NDK 目前开发方案 | NDK 编译 | 导入 so 库 | 项目编码转换)_ico_02



.







3. 使用 Source Insight 查看 NDK 源码




中文乱码问题​ : SourceInsight 不支持 UTF-8 格式的编码, 这里需要将 UTF-8 的项目转为 GBK 格式的, 然后再导入到 SourceInsight 中;

Android Studio NDK 代码 Source Insight调试 (NDK 目前开发方案 | NDK 编译 | 导入 so 库 | 项目编码转换)_android_03


转换命令 ​: 创建一个 convert 目录, 其中有两个目录 jni_utf-8 和 jni_gb18030 目录, 下面的命令用于 两种编码之间的转换;

-- ​GBK 转 UTF-8​ : 进入 jni_gb18030 目录, 执行下面的命令;

bogon:jni octopus$ cp -R . ../jni_utf-8 
bogon:jni octopus$ find . -type f -exec bash -c 'iconv -f GB18030 "{}" 1>/dev/null 2>/dev/null && iconv -f GB18030 -t utf-8 "{}" > ../jni_utf-8/"{}"' \;



-- ​UTF-8 转 GBK​ : 进入 jni_utf-8 目录, 执行下面的命令;


bogon:jni octopus$ cp -R . ../jni_gb18030
bogon:jni octopus$ find . -type f -exec bash -c 'iconv -f utf-8 "{}" 1>/dev/null 2>/dev/null && iconv -f utf-8 -t GB18030 "{}" > ../jni_gb18030/"{}"' \;



拷贝项目​ : 将转换后的 jni_gb18030 目录中的项目拷贝到 SourceInsight 中即可查看该项目;

Android Studio NDK 代码 Source Insight调试 (NDK 目前开发方案 | NDK 编译 | 导入 so 库 | 项目编码转换)_新版本_04