Mac 下配置NDK/JNI开发环境,并运行简单demo

时间:2024-05-19 07:01:11

1.去NDK官网下载mac版的ndk,然后自己解压出来。

2.打开androidStudio正常新建一个显示"hello world" 的android工程.

3.配置NDK路径

  (a)点击菜单栏File, ProjectStructure

  (b)在弹出的窗口里,左侧选中SDKLocation

  (c)然后在右侧Android NDK Location中填入刚才解压出来的NDK目录的路径,如图:

Mac 下配置NDK/JNI开发环境,并运行简单demo

上面蓝色选中的路径就是我的NDK存放的路径。

4.编译生成.class文件。点菜单栏的Build, Make Project

  这时,在工程的app/build/intermediates下就会生成classes文件夹,打开classes目录下的debug目录就会看到以你的包名命名的各级文件夹,最里边文件夹下有Java类对应的.class文件

5.假如现在要在mainActivity引用jni方法。在MainActivity类里添加下面代码

static {

        System.loadLibrary("myNativeLib");

    }

这是用于声明本地代码库。

6.定义native方法(先在java层定义,待会到C里面去实现内容)。比如输入:

public native String getStringFromNative();

7.使用javah命令行生成jni目录及对应的头文件。

  (a)进入当前java目录,也就是包的外层的目录(src/main/java)。

  (b)在androidStudio下面底部的终端(Terminal)输入:

javah -d ../jni 你的包名.引用本地方法的类的名称

javah意思是生成一个.h头文件,-d ../jni的意思是生成一个位置是在当前目录(src/main/java)的上一级目录(即src/main目录)名字叫做jni的文件夹(directory);

比如我的工程下,这条命令是

javah -d ../jni com.example.yucan.mytest.MainActivity

然后就可以在工程目录下看到新建的jni文件夹下的头文件:

Mac 下配置NDK/JNI开发环境,并运行简单demo

到这里,我们就基本相当于完成了相当于Eclipse中的add native support功能了。

8.配置app模块下的build.gradle文件。

在build.gradle的defaultConfig下加入以下ndk配置:

ndk {

            moduleName"myNativeLib"

            abiFilters "armeabi", "armeabi-v7a", "x86"

        }

其中moduleName是与上面在Java类中使用System.loadLobrary(“本地库名称”);以及生成的.so文件名称对应的;

abiFilters指的是我们要生成哪些平台的so文件,这里生成arm平台和x86平台;

配置完成,如图:

Mac 下配置NDK/JNI开发环境,并运行简单demo

这一步有点像我们eclipse中配置.mk文件

9.打开工程目录下的local.properties。看看是否有这行代码

ndk.dir=/Users/yucan/NDK/android-ndk-r14b

如果上面配好了NDK路径,讲道理是有的,如果没有自己按照自己的NDK路径加上去。

10.打开工程目录下的gradle.properties文件,在文件的最后一行加入:

android.useDeprecatedNdk=true

这句的作用是允许我们使用已经过时的NDK版本,不知道AndroidStudio要求使用哪个版本的NDK才不会报错,总之只要配置了这一句就可以使用比较旧的NDK版本了。

11.接下来就是写C层的代码了(可以自己去用其他软件写,都可以)。

为了方便,我现在就就在刚才的jni文件夹里写吧。

(a)首先右键jni文件夹,创建一个.h头文件。

Mac 下配置NDK/JNI开发环境,并运行简单demo

随便取名,比如我取名myH

(b)然后将com_example_yucan_mytest_MainActivity.h文件的内容直接复制粘贴到myH.h文件去。

myH.h代码如下:

//
// Created by yuCan on 2017/10/12.
//

#ifndef MYTEST_MYH_H
#define MYTEST_MYH_H

#endif //MYTEST_MYH_H

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_yucan_mytest_MainActivity */

#ifndef _Included_com_example_yucan_mytest_MainActivity
#define _Included_com_example_yucan_mytest_MainActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_example_yucan_mytest_MainActivity
 * Method:    getStringFromNative
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_example_yucan_mytest_MainActivity_getStringFromNative
        (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

细心的肯定发现了,这个头文件已经声明了一个jni方法。那我们就去实现他。

(c)在新建一个c文件(记住是c文件,不是c++)

当然c++也可以,代码写起来有一丝丝不一样而已。我以c为例。

创建好后(自己随便命名,比如我叫myNewTest),敲一下刚才.h声明的方法的实现。代码如下:

//
// Created by yuCan on 2017/10/12.
//

#include "myH.h"


JNIEXPORT jstring JNICALL Java_com_example_yucan_mytest_MainActivity_getStringFromNative
        (JNIEnv * env, jobject jobj){
    return (*env)->NewStringUTF(env, "hello JNI,I'm coming");
}

到这一步,我们基本就实现了c层的代码了,也就是刚才的native方法的具体实现。

12.在Android程序调用这个在c层实现的方法.我就写一个简单的调用方法。整个MainActivity代码如下:

package com.example.yucan.mytest;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    static {

        System.loadLibrary("myNativeLib");

    }
    public native String getStringFromNative();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toast.makeText(this, getStringFromNative(), Toast.LENGTH_SHORT).show();
    }
}

现在整个工程基本就已经实现了

13.点菜单栏的Build->Make Project编译一下工程。

编译完成之后,在工程目录下app/build/intermediates/ndk/debug/lib目录下应该就成功生成了相应的.so文件,而且会生成对应平台的.so文件。

debug目录下还自动生成了Android.mk文件,相当于我们用build.gradle文件的配置替代了Android.mk文件的配置。如图:

Mac 下配置NDK/JNI开发环境,并运行简单demo

现在就可以将项目运行到真机上去看效果了。

如果不知道mac 使用androidStudio到android真机调试应用点击这里

可以看到真机toast了一下

"hello JNI,I'm coming"

效果图在真机上,就不截屏看了。

这就是整个AndroidStudio中配置了NDK/JNI开发环境的全部过程。