[Android jni开发系列(二)]AndroidStudio移植eclipse NDK项目开发

1、在eclipse上开发ndk项目时一般都是在项目里新建jni目录,通过编写Android.mk和Application.mk编译生成so库,然后放到libs目录下就可以使用,下面来看下,在AndroidStudio怎么采用这种方式生成so。

2、利用AndroidStudio配置几个需要用到的快捷命令,javah、ndk-build、ndk-build clean,具体作用如下:

javah:根据java文件生成对应的jni头文件
[Android jni开发系列(二)]AndroidStudio移植eclipse NDK项目开发_第1张图片

Program$JDKPath$\bin\javah.exe
Parameters:-classpath . -jni -d $ModuleFileDir$\src\main\jni $FileClass$
Working directory:$ModuleFileDir$\src\main\java

ndk-build:ndk编译生成so
[Android jni开发系列(二)]AndroidStudio移植eclipse NDK项目开发_第2张图片

\\ndk路径
Program:D:\adt-bundle-windows-x86_64-20140702\android-ndk-r15c\ndk-build.cmd  
Parameters:
Working directory:$ProjectFileDir$\app\src\main\

ndk-build clean:清除ndk编译环境
[Android jni开发系列(二)]AndroidStudio移植eclipse NDK项目开发_第3张图片

\\ndk路径
Program:D:\adt-bundle-windows-x86_64-20140702\android-ndk-r15c\ndk-build.cmd  
Parameters:clean
Working directory:$ProjectFileDir$\app\src\main\

3、快捷命令配置好后,就可以开始了,选中需要生成jni头文件的java类,右键——>External Tool——>javah
[Android jni开发系列(二)]AndroidStudio移植eclipse NDK项目开发_第4张图片
会自动新建jni目录,并生成对应的jni头文件

    public class NdkTest {
        static {
            System.loadLibrary("test_ndk");
        }

        public native String getString();
    }

通过上面方式生成的头文件“com_jason_jni_demo2_NdkTest.h”

/* DO NOT EDIT THIS FILE - it is machine generated */
    #include 
    /* Header for class com_jason_jni_demo2_NdkTest */

    #ifndef _Included_com_jason_jni_demo2_NdkTest
    #define _Included_com_jason_jni_demo2_NdkTest
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     com_jason_jni_demo2_NdkTest
     * Method:    getString
     * Signature: ()Ljava/lang/String;
     */
    JNIEXPORT jstring JNICALL Java_com_jason_jni_demo2_NdkTest_getString
      (JNIEnv *, jobject);

    #ifdef __cplusplus
    }
    #endif
    #endif

编写头文件对应的NdkTest.c文件实现getString方法

/* DO NOT EDIT THIS FILE - it is machine generated */
#include 
/* Header for class com_jason_jni_demo2_NdkTest */

#ifndef _Included_com_jason_jni_demo2_NdkTest
#define _Included_com_jason_jni_demo2_NdkTest
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class:     com_jason_jni_demo2_NdkTest
* Method:    getString
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_jason_jni_demo2_NdkTest_getString
(JNIEnv * env, jclass clazz){
   char * hello = "Hello World JNI2";
         return  (*env)->NewStringUTF(env,hello);
}

#ifdef __cplusplus
}
#endif
#endif

3、文件编写好后,就剩下Android.mk和Application.mk了,可根据自己情况编写,下面提供一个简单的demo

Android.mk具体内容:

    LOCAL_PATH := $(call my-dir)

    include $(CLEAR_VARS)

    LOCAL_MODULE    := test_ndk
    LOCAL_SRC_FILES := NdkTest.c

    include $(BUILD_SHARED_LIBRARY)

Application.mk具体内容:

    APP_MODULES := test_ndk
    APP_ABI := all

4、万事俱备,只差编译了,这时配置的ndk-build命令又派上用场了,选中jni目录右键——>External Tool——>ndk-build
[Android jni开发系列(二)]AndroidStudio移植eclipse NDK项目开发_第5张图片
执行完这个命令后,会在jni同级目录生成libs目录和对应的so库,这时候就可以像之前一样使用了,但需要注意的是AndroidStudio 默认指定是加载jniLibs下的so,所以需要把libs目录改为jniLibs或者
在build.gradle里指定so的目录

sourceSets {
   main {
       jniLibs.srcDirs = ['src/main/libs']
   }
}

另外还有个问题需要注意,如果是在AndroidStudio里直接这样编译apk会出现编译出错,如下:

  FAILURE: Build failed with an exception.

    * What went wrong:
    Execution failed for task ':app:compileDebugNdk'.
    > Error: Your project contains C++ files but it is not using a supported native build system.
    Consider using CMake or ndk-build integration with the stable Android Gradle plugin:
     https://developer.android.com/studio/projects/add-native-code.html
    or use the experimental plugin:
     https://developer.android.com/studio/build/experimental-plugin.html.


    * Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

    BUILD FAILED

这是因为如果’src/main/jni’存在的话,AndroidStudio会采用自带的方式去编译生成so库,此时可以在build.gralde添加如下代码修复此问题:

    defaultConfig {
        applicationId "com.jason.jni.demo2"
        minSdkVersion 21
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        sourceSets {
            main {
                jniLibs.srcDirs = ['src/main/libs']
                jni.srcDirs = [] jni目录存在AndroidStudio会采用自身方式生成so库,需要配置这个,不然编译项目时候会出现上面的错误
            }
        }
    }

源码下载地址

你可能感兴趣的:(Android学习)