android studio3.0 使用ndk-build配置第一个NDK程序

当前android studio 版本3.0.1,步骤如下:

1.设置jni -h 和ndk -build的快捷方式

2.java代码写native方法以及设置动态链接库

3.快捷键jni -h生成头文件.h

4.建立c++资源文件和两个mk文件

5.快捷键ndk-build生成三种.so库文件

6.将生成的main/libs文件夹内的so文件复制到app/libs下,并删除main下新生成的jni、libs、obj三个文件夹(可选)。

7.在build.gradle中的android闭包和buildTypes闭包中分别添加sourceSets().

以上是步骤,具体如下:

1.置jni -h 和ndk -build的快捷方式:

新建项目,成功后点击File,然后找到Settings…点击找到External Tools,然后如下图添加java -jni快捷键
这里写图片描述
Tool settings中三行可以直接copy上去:
$JDKPath$\bin\javah.exe
-classpath . -jni -d $ModuleFileDir$/src/main/jni $FileClass$
$ModuleFileDir$\src\main\java

扫描二维码关注公众号,回复: 2790232 查看本文章

添加ndk-build快捷键如下图:
这里写图片描述
Tool settings 的两行:

F:\software\androidstudio\sdk\ndk-bundle\ndk-build.cmd(根据自己的ndk目录设置这个路径)

$ModuleFileDir$\src\main(直接copy)

使用方式:选中C/C++文件—>右键—>ExternalTools—>ndk-build,将在main文件夹下生成libs文件夹以及多个so文件,我们可以移动至jniLibs目录下去。

2.java代码写native方法以及设置动态链接库

public class JniTest {

    /**
     * 将用C++代码实现,在android代码中调用的方法:获取一段文字
     */
    public static native String getStrFromC();

    /**
     * 配置加载的so库的文件名字===>如 :libmyLib.so
     */
    static {
        System.loadLibrary("myLib");
    }
}

注意此处的myLib将与android.mk中的LOCAL_MODULE属性值一致;

3.快捷键jni -h生成头文件.h
然后对该文件执行javah -jni操作,生成对应的.h头文件。
这里写图片描述

这里写图片描述

如图,已经根据我们的java类在jni文件夹下生成了对应的.h文件,文件名为包名类名.h,我们可以手动改.h文件名,里面只有一个方法,返回值为String(jstring),方法名为Java类的包名类名方法名(包名中的分级不是用.而是_),前面两个参数是C++里面必须有的(JNIEnv代表指向JVM的指针,jclass是调用该方法的java对象),第三个jobject就是我们java类的方法里面的参数Object。注意,这是java函数与C++函数对应的静态注册方法,即通过特定的规则来写。此处方法名可以随意起名字,然后还可以用动态注册的方式关联两个方法。

4.建立c++资源文件和两个mk文件
在jni文件夹下,新建一个.c(c语言)或者.cpp(c++)的文件,来实现.h文件里声明的方法:
把.h文件里面声明的方法拷贝到新建的c文件里面,然后在文件里面引入.h文件,如下图:
这里写图片描述

至此,.h文件和c++文件已完成,想生成so文件还需要在这个jni目录下增加两个文件,Android.mk和Application.mk。

  • Android.mk

注意LOCAL_MODULE的值与之前的java类中设置要生成so库的名字相对应,LOCAL_SRC_FILES的值写c++文件的名字,这两个值成对设置,可设置多组。(:=是赋值的意思,$是引用某变量的值。)

LOCAL_PATH := $(call my-dir)     // 设置当前的编译目录(Android.mk所在的目录) 
include $(CLEAR_VARS)            // 清除LOCAL_XX变量(LOCAL_PATH除外)
LOCAL_MODULE := myLib // 指定当前编译模块的名称  
LOCAL_SRC_FILES := jnittest.c    // 编译模块需要的源文件
include $(BUILD_SHARED_LIBRARY) // 指定编译出的库类型,BUILD_SHARED_LIBRARY:动态库;BUILD_STATIC_LIBRARY:静态库, BUILD_EXECUTEABLE指:可执行文件

在一个Android.mk文件中配置多个Module的方式如下(include$(CLEAR_VARS)、include $(BUILD_SHARED_LIBRARY)两个语句也需要加上)

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := myLib
LOCAL_SRC_FILES := jnittest.c
include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := myLib2
LOCAL_SRC_FILES := jnittest2.c
include $(BUILD_SHARED_LIBRARY)
  • Application.mk
APP_ABI := all

5.生成so文件
对C++文件执行ndk-build操作,生成相应的so文件
这里写图片描述
这里写图片描述

6.将生成的main/libs文件夹内的so文件复制到app/libs下,并删除main下新生成的jni、libs、obj三个文件夹(可选)。

7.在build.gradle中的android闭包和buildTypes闭包中分别添加sourceSets().
这里写图片描述

android {
    compileSdkVersion 26



    defaultConfig {
        applicationId "com.example.testopencv"
        minSdkVersion 15
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

    }

    sourceSets {
        main {
            //让AS识别libs下的.so第三方包
            jniLibs.srcDirs =['libs']
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }

        sourceSets {
            main {
                jni.srcDirs = []
            }
        }
    }

}

猜你喜欢

转载自blog.csdn.net/sinat_29355599/article/details/81292856