https://codelabs.developers.google.com/codelabs/android-studio-jni/index.html

https://developer.android.com/ndk/samples/index.html

https://github.com/googlesamples/android-ndk/tree/android-mk/hello-jni

code https://github.com/AndroidDevLog/AndroidDevLog

  • 新建一个Android Project,然后新建一个Java类,命名为:Jni.java
public class Jni {
    public native String getJniString();

    static {
        System.loadLibrary("JNI"); //和生成so文件的名字对应。
    }
}

Jni.png

  • 然后在MainActivity中调用这个方法。 将这个方法的返回值,显示在界面上。然后 build project
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // new code here
        Jni jniUtils = new Jni();
        TextView tv = (TextView) findViewById(R.id.textView);
        tv.setText(jniUtils.getJniString());
        // end code
    }
}

MainActivity.png

  • 利用 javah 根据生成的class文件生成对应的 .h头文件

构建项目成功后。点开AS的标签,cd命令进入到该项目的app/build/intermediates/classes/debug/ 文件夹下。

$ cd app/build/intermediates/classes/debug
$ javah -jni com.iosdevlog.a26jni.Jni

Terminal.png

  • 在工程的main目录下新建一个名字为jni的目录,然后将刚才的 .h文件剪切过来。
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_iosdevlog_a26jni_Jni */

#ifndef _Included_com_iosdevlog_a26jni_Jni
#define _Included_com_iosdevlog_a26jni_Jni
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_iosdevlog_a26jni_Jni
 * Method:    getJniString
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_iosdevlog_a26jni_Jni_getJniString
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

com_iosdevlog_a26jni_Jni.h.png

  • jni目录下新建一个c文件。
#include "com_iosdevlog_a26jni_Jni.h"

JNIEXPORT jstring JNICALL Java_com_iosdevlog_a26jni_Jni_getJniString
  (JNIEnv *env, jobject obj) {
    return (*env)->NewStringUTF(env, "This is 'Hello World!' from JNI!");
}

com_iosdevlog_a26jni_Jni.c.png

  • 在app module目录下的build.gradle中设置库文件名(生成的so文件名)。

找到gradle文件的defaultConfig这项,在里面添加如下内容:

        ndk{
            moduleName "JNI"         //生成的so名字
            abiFilters "armeabi", "armeabi-v7a", "x86"  //输出指定三种abi体系结构下的so库。
        }

build.gradle.app.png

  • 最后在项目的 gradle.properties 文件的末尾添加如下代码:
android.useDeprecatedNdk=true

gradle.properties.png

  • 重新编译项目并运行。

so