Android NDK开发之HelloWorld

一、准备工作

  1. 下载NDK开发包:android-ndk-r16b-windows-x86_64.zip

  2. 解压NDK,解压路径需要全英文,并且不允许有空格(不可以解压到C:\Program Files路径)。此文中,我的解压路径为:D:\Android\android-ndk,此处的android-ndk为我修改后的文件夹名称,你也可以不修改,保留解压后的原始名称

  3. Android Studio中新建project,路径需要全英文,并且不允许有空格,命名为HelloJNI, 包名为:com.jni

  4. 按照下图,设置项目的NDK路径
    Android NDK开发之HelloWorld_第1张图片

  5. 路径设置结束后,等待项目重新构建完成,然后按照下图,查看local.properties文件中是否有了ndk.dir=D\:\\Android\\android-ndk字样,如果有,代表NDK路径设置成功
    Android NDK开发之HelloWorld_第2张图片

二、编写代码

  1. 新建java类HelloJava(自己随便定义,我这里加了后缀Java作为标记供读者区分),并在类中声明本地方法

    package com.jni;
    
    public class HelloJava {
        static{
            System.loadLibrary("HelloUtil");
        }
        public static native String getHelloFromJNI();
    }
    
  2. 工具栏上执行Build→Make Project操作,生成class
    Android NDK开发之HelloWorld_第3张图片

  3. 查看class文件是否生成
    Android NDK开发之HelloWorld_第4张图片

  4. Terminal中,输入指令生成头文件javah -d jni -classpath android.jar;app/src/main/java com.jni.HelloJava。注意:如果你未对sdk设置环境变量,可把android.jar替换为[你的sdk路径]\platforms\android-22\android.jar
    Android NDK开发之HelloWorld_第5张图片

  5. 在project下,新增了一个jni文件夹,生成的头文件就在其中。如果可以看到,则证明头文件生成成功。
    Android NDK开发之HelloWorld_第6张图片

  6. jni目录下新建HelloC.c(自己随便定义,我这里加了后缀C和后缀Java区分),include刚才生成的头文件,然后补全方法。
    Android NDK开发之HelloWorld_第7张图片

    #include "com_jni_HelloJava.h"
    
    JNIEXPORT jstring JNICALL Java_com_jni_HelloJava_getHelloFromJNI(JNIEnv *env, jclass thiz)
    {
        return (*env)->NewStringUTF(env, "Hello World From JNI!");
    }
    

三、编译.so包

  1. 在刚才的jni目录下,新建Android.mk文件,写入以下内容,第3、4行分别对应之前的moduleName和C源码

    LOCAL_PATH := $(call my-dir)
    include $(CLEAR_VARS)
    LOCAL_MODULE    := HelloUtil
    LOCAL_SRC_FILES := HelloC.c
    include $(BUILD_SHARED_LIBRARY)
    
  2. 在刚才的jni目录下,新建Application.mk文件,写入以下内容

    APP_ABI := all
    
  3. 在app路径下的build.gradle中,配置ndk节点,moduleNameHelloJava代码中要加载的.so库名字要保持一致。其层级结构如下,配置完成后点击右上角的Sync Now同步一下。

    android {
        defaultConfig {
        	//其他配置.........
            //ndk节点
            ndk{
                moduleName "HelloUtil"
                ldLibs "log", "z", 'm'
                abiFilters "armeabi", "armeabi-v7a", "x86"
            }
        }
    }
    
  4. Terminal中,输入ndk-build指令编译.so包,看到有.so输出,证明生成成功
    Android NDK开发之HelloWorld_第8张图片
    Android NDK开发之HelloWorld_第9张图片

四、调用

  1. 以上生成的.so文件还无法供HelloJava类进行加载和使用,需要拷贝到app\libs路径下,如下图所示:
    Android NDK开发之HelloWorld_第10张图片

  2. 将.so拷贝至对应目录后,还应在app路径下的build.gradle中,该指定jniLibs。其层级结构如下,配置完成后点击右上角的Sync Now同步一下。

    android {
    	//增加sourceSets节点,并配置jniLibs路径
        sourceSets {
            main {
                jniLibs.srcDirs = ['libs']
            }
        }
    }
    
  3. MainActivity中调用HelloJava.,运行项目,出现吐司,成功。

        @Override
        protected void onResume() {
            super.onResume();
            String helloStr = HelloJava.getHelloFromJNI();
            Toast.makeText(this, helloStr, Toast.LENGTH_SHORT).show();
        }
    

五、源码

https://github.com/1992YoungHong/HelloJNI

你可能感兴趣的:(开发笔记)