Android NDK HelloJni

Android NDK Hello Jni

一篇博客专家的文章:Android:JNI 与 NDK到底是什么?(含实例教学)

简单实现一个HelloJni的Demo

名词解释
  • JNI 全称 Java Native Interface,即Java本地接口
  • NDK全称 Native Development Kit,是Google在Android开发中提供的一套用于快速创建native工程的一个工具
Android Studio 2.2 以下 & 2.2以上 两种实现

Android Studio 2.2 以下

  1. 首先确保Android Studio配置好了NDK环境
    Android NDK HelloJni
    Android NDK HelloJni

  2. 在Gradle 的 gradle.properties中添加配置

# 对旧版本的NDK支持
android.useDeprecatedNdk=true 
  1. 在Gradle的build.gradle添加ndk节点
defaultConfig {
        ......
        ndk {
            // 模块名称,即编译的.so文件名
            moduleName "hello_jni"

            // 使用STL标准库(默认情况下JNI中是无法使用STL标准库的)
            stl "stlport_static"
            // "log" 表示加入Android的调试日志,只要在导入#include <android/log.h>
            // 就可使用__android_log_print方法打印日志到logcat中
            ldLibs "log"

            // 指定ndk需要兼容的架构,把除了v7a以外的兼容包都过滤掉,只剩下一个v7a
            // 1. 减少包体积
            // 2. 支持Android主流CPU架构即可
            abiFilters "armeabi-v7a"
        }
    }
  1. src/main/jni 目录下 创建本地代码文件 test.cpp
# include <jni.h>
# include <stdio.h>

extern "C"
{
	// 格式 = Java _包名 _ 类名_Java需要调用的方法名 
    JNIEXPORT jstring JNICALL Java_cn_cutcopy_jni_JniUtil_getStringFromJNI(JNIEnv *env, jobject obj ){
    return env -> NewStringUTF("Hello i am from JNI!");
	}
}

  1. src/main/jni 目录下 创建本地代码文件 Android.mk
LOCAL_PATH       :=  $(call my-dir)
include              $(CLEAR_VARS)
LOCAL_MODULE     :=  hello_jni
LOCAL_SRC_FILES  :=  test.cpp
include              $(BUILD_SHARED_LIBRARY)
  1. src/main/jni 目录下 创建本地代码文件 Application.mk
// 这里我们只生成v7架构的.so
APP_ABI := armeabi-v7a
  1. 通过上述4,5,6三个本地文件编译生成.so
// 进入到test.cpp目录下,执行以下命令
// 当然前提是你电脑已经配置好了ndk环境变量
ndk-build
// 编译成功后,在src/main/会多了两个文件夹libs,obj,其中libs下存放的是.so库文件
  1. 在src/main下创建jniLibs目录,将libs下对应CPU架构的.so文件复制到该目录下
    Android NDK HelloJni

  2. 接下来看Java中调用

public class MainActivity extends Activity {
	
	private Button mButton;
	
	// 步骤1:加载生成的so库文件
    // 注意要跟.so库文件名相同
    static {
        System.loadLibrary("hello_jni");
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 通过Button调用JNI中的方法
        mButton = (Button) findViewById(R.id.button);
        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mButton.setText(JniUtil.getStringFromJNI());
            }
        });
    }
}
  1. cn/cutcopy/jni包下JniUtil就定义一个方法
public class JniUtil {
    public  static native  String getStringFromJNI();
}

附上源码,供大家方便调试加深理解

Android Studio 2.2 以上

下篇再讲;)