使用NDK和swig工具来批量编译c++代码还是很方便的。我之前写过一篇eclipse版本的,现在终于有空把android studio的版本弄好。eclipse版本地址:Android ndk开发swig编译jni接口 。在这篇博客我会介绍相关配置,生成自动生成接口jar以及so库。这期间涉及很多踩坑,做好准备。本篇博客篇幅比较长。

官方网址:http://www.sureshjoshi.com/mobile/android-ndk-in-android-studio-with-swig/

swig官网:http://www.swig.org/exec.html

swig工具下载网址:http://www.swig.org/download.html

我的博客资源提供的swig工具资源:http://download.csdn.net/download/qq_16064871/10046580

这篇博客的代码:http://download.csdn.net/download/qq_16064871/10044371

GitHub 的大神写示例代码:https://github.com/sureshjoshi/android-ndk-swig-example

1、配置篇

系统环境变量的配置,加在path那里

E:\Android\sdk\platform-tools;    方便使用adb命令
C:\Program Files\Android\Android Studio\gradle\gradle-2.14.1;  
F:\software\swigwin-3.0.2;    swig编译需要
E:\Android\sdk\ndk-bundle;    这个是android studio 的自动下载的NDK目录,编译生成so需要

有了这些,我们可以在Android studio 的Terminal命令行操作。

注意:swig工具包解压就行,然后配置在path路径即可

2、编译接口jar

编译生成接口jar的build配置如下

// For this to work, it's assumed SWIG is installed// TODO: This only works when called from Command Line (gradlew runSwig)task runSwig(type:Exec, dependsOn: ['createCoreWrapperDir']) {    String osName = System.getProperty("os.name").toLowerCase();    if (osName.contains("windows")) {        workingDir '/src/main/jni'   // This implicitly starts from $(projectDir) evidently        commandLine 'cmd', '/c', 'swig'        args '-c++', '-java', '-package', 'com.swig.test', '-outdir', coreWrapperDir.absolutePath, 'Unix.i'    }    else {        commandLine 'swig'        args '-c++', '-java', '-package', 'com.swig.test', '-outdir', coreWrapperDir.absolutePath, "${projectDir}/src/main/jni/Unix.i"    }}
有了这个配置:

可以在项目找到grade project 里面的 other 里面找到你的配置

android studio 使用NDK和swig编译c++示例_第1张图片

双击编译即可,前提是你的android studio只打开一个,相信很多小伙伴都知道的吧。

自动编译生成的代码:

android studio 使用NDK和swig编译c++示例_第2张图片

编译生成接口的包名,后面使用时候不能再改了,因为生成so是根据jni文件下下面Unix_wrap.cxx这个文件生成的。里面类的函数已经包括编译的包名,所以变了包名,使用时候报错。

生成jar时候记得在jni那个类里面加上加载库的代码,(这个先提前说了)

public class JniDmeoLibJNI {  static {    System.loadLibrary("JniDmeoLib");  }  public final static native long new_CTest();  public final static native void delete_CTest(long jarg1);  public final static native double CTest_getTest(long jarg1, CTest jarg1_, double jarg2, double jarg3);  public final static native long new_CoutputChar();  public final static native void delete_CoutputChar(long jarg1);  public final static native String CoutputChar_getfileName(long jarg1, CoutputChar jarg1_);  public final static native void CoutputChar_setfileName(long jarg1, CoutputChar jarg1_, String jarg2);}
下面看一下完整的ndkBuild的配置

apply plugin: 'com.android.library'android {    compileSdkVersion 24    buildToolsVersion "24.0.1"    defaultConfig {        minSdkVersion 15        targetSdkVersion 24        versionCode 1        versionName "1.0"        ndk {            moduleName "JniDmeoLib"            abiFilters "armeabi"        }    }    lintOptions{        abortOnError false    }    buildTypes {        release {            minifyEnabled false            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'        }    }}dependencies {    compile fileTree(dir: 'libs', include: ['*.jar'])    testCompile 'junit:junit:4.12'    compile 'com.android.support:appcompat-v7:24.2.1'}// Location of where to store the jni wrapped filesdef coreWrapperDir = new File("${projectDir}/src/main/java/com/swig/test")task createCoreWrapperDir {    coreWrapperDir.mkdirs()}// For this to work, it's assumed SWIG is installed// TODO: This only works when called from Command Line (gradlew runSwig)task runSwig(type:Exec, dependsOn: ['createCoreWrapperDir']) {    String osName = System.getProperty("os.name").toLowerCase();    if (osName.contains("windows")) {        workingDir '/src/main/jni'   // This implicitly starts from $(projectDir) evidently        commandLine 'cmd', '/c', 'swig'        args '-c++', '-java', '-package', 'com.swig.test', '-outdir', coreWrapperDir.absolutePath, 'Unix.i'    }    else {        commandLine 'swig'        args '-c++', '-java', '-package', 'com.swig.test', '-outdir', coreWrapperDir.absolutePath, "${projectDir}/src/main/jni/Unix.i"    }}

2、生成so库

在android studio 的Terminal命令终端去找到你要编译项目下的jni目录

然后输入ndk-build 即可,如下图

android studio 使用NDK和swig编译c++示例_第3张图片

如果图片看不清楚,就可下面这个

D:\SwigNdkDemo>cd D:\SwigNdkDemo\buildNdk\src\main\jniD:\SwigNdkDemo\buildNdk\src\main\jni>ndk-buildAndroid NDK: APP_PLATFORM not set. Defaulting to minimum supported version android-14.Android NDK: WARNING: APP_PLATFORM android-14 is higher than android:minSdkVersion 1 in D:/SwigNdkDemo/buildNdk/src/main/AndroidManifest.xml. NDK binaries will *not* be comptible with devices older than android-14. See https://android.googlesource.com/platform/ndk/+/master/docs/user/common_problems.md for more information.[armeabi] Install        : libJniDmeoLib.so => libs/armeabi/libJniDmeoLib.soD:\SwigNdkDemo\buildNdk\src\main\jni>

3、打包jar

后面我又弄了一个library打包jar。把之前那个生成目录代码,原封不动拷贝到那个工程,记得包名也不变。

然后配置

task makeJar(type: Copy){    delete'libs/JniDmeoLib.jar'    from('build/intermediates/bundles/release/')    into('libs/')    include('classes.jar')    rename('classes.jar','JniDmeoLib.jar')}makeJar.dependsOn(build)

这个配置也是可以在other那里找到的。

4、测试jar和so

android studio 使用NDK和swig编译c++示例_第4张图片

5、过程中遇到问题

包括编译其他项目

Error:Execution failed for task ':app:runSwig'.
> Process 'command 'cmd'' finished with non-zero exit value 1
出现这个错误的原因是
swig没有在系统环境变量里面path配置。


E:\Android\Sdk\ndk-bundle\build\core\add-application.mk
Error:(101) *** Android NDK: Aborting...    .  Stop.
Error:Execution failed for task ':app:compileDebugNdk'.
> com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: 
Process 'command 'E:\Android\sdk\ndk-bundle\ndk-build.cmd'' finished with non-zero exit value 2
这个错误主要是项目的目录层级太深,移动一下即可。这个问题比较奇怪。


编译so,就是使用Terminal命令行在进入要编译项目的jni文件夹。然后输入ndk-build,一回车就可以了。
F:\SVN Android studio\Android_Lib>cd F:\SVN Android studio\Android_Lib\jnidemo\src\main\jni
F:\SVN Android studio\Android_Lib\jnidemo\src\main\jni>ndk-build
Android NDK: Your Android application project path contains spaces: 'F: . studio/Android_Lib/jnidemo/src/main'
Android NDK: The Android NDK build cannot work here. Please move your project to a different location.
E:\Android\sdk\ndk-bundle\build\\..\build\core\build-local.mk:158: *** Android NDK: Aborting.    .  Stop.
出现上面这个错误,就是说你的工程需要换个目录编译,一般来说目录层级不能太深


编译成功的结果
F:\Android_Lib>cd F:\Android_Lib\jnidemo\src\main\jni
F:\Android_Lib\jnidemo\src\main\jni>ndk-build
Android NDK: APP_PLATFORM not set. Defaulting to minimum supported version android-14.
Android NDK: WARNING: APP_PLATFORM android-14 is higher than android:minSdkVersion 1 in F:/Android_Lib/jnidemo/src/main/AndroidManifest.xml. NDK binaries will *not* be comptible
 with devices older than android-14. See https://android.googlesource.com/platform/ndk/+/master/docs/user/common_problems.md for more information.
[arm64-v8a] Install        : libcurvelib.so => libs/arm64-v8a/libcurvelib.so
[x86_64] Install        : libcurvelib.so => libs/x86_64/libcurvelib.so
[mips64] Install        : libcurvelib.so => libs/mips64/libcurvelib.so
[armeabi-v7a] Install        : libcurvelib.so => libs/armeabi-v7a/libcurvelib.so
[armeabi] Install        : libcurvelib.so => libs/armeabi/libcurvelib.so
[x86] Install        : libcurvelib.so => libs/x86/libcurvelib.so
[mips] Install        : libcurvelib.so => libs/mips/libcurvelib.so


其他代码就不贴了。可能会有一些疏漏。还是自已尝试编译跑一遍好。

我博客关于swig文章还是有几篇,有需要的可以看一下。




更多相关文章

  1. 第一行代码笔记1
  2. Android 5.1.1 源码目录结构
  3. Android AutoCompleteTextView示例教程
  4. 第一行代码:AlertDialog
  5. Android 自动更新代码
  6. Android 自制一个工作日历 原代码
  7. android 网络视频代码
  8. android版本更新代码
  9. 系出名门 Android源代码

随机推荐

  1. Android的selector,背景选择器
  2. Android的Adapter用法理解
  3. android中的selector背景选择器
  4. android http协议添加Authorization认证
  5. Android(安卓)Gson的使用
  6. H5做的商城客户端,效果很不错
  7. android Adapter综合介绍
  8. versionCode与versionName的区别、应用、
  9. Google Android应用开发04 Android应用程
  10. Android开发资源完全汇总