JNI在Android中的实践NDK:Hello World

Java层入口

对要在C层实现的方法加native修饰符

public class NDKTools {
    static {
        System.loadLibrary("ndktest-jni");
    }
    public static native String getStringFromNDK();
}

Activity中使用该方法,该方法会从Native层返回一个字符串显示在屏幕上。我这里用了MVP设计模式,无视他就可以了。

public class NDKActivity extends BaseMvpActivity {
    TextView ndkTv;

    @Override
    public void initView() {
        ndkTv = findViewById(R.id.ndk_tv);
    }

    @Override
    public void initData() {
        ndkTv.setText(NDKTools.getStringFromNDK());
    }

    @Override
    public int getLayoutId() {
        return R.layout.activity_ndk;
    }

    @Override
    public void showLoading() {

    }

    @Override
    public void hideLoading() {

    }

    @Override
    public void refreshView() {

    }

    @Override
    public void onError(String errMessage) {

    }
}

自动生成.h文件

编译java文件,生成.class文件

javac NDKTools.java

生成的字节码文件

输入javah -jni com.billshen.offerlearn.util.NDKTools,根据class生成h头文件。注意这里要cd到java根目录。

 会在java根目录下生成一个h头文件

在main目录下新建一个jni目录,同时新建一个c文件和一个Android.mk,并把刚才那个h文件拷过来。当然h文件你自己写也是可以的,这样自动生成快一点,而且规范。

 ndk_test.c文件实现h文件中的方法,需要导入刚才的头文件。

#include "com_billshen_offerlearn_util_NDKTools.h"

JNIEXPORT jstring JNICALL Java_com_billshen_offerlearn_util_NDKTools_getStringFromNDK
  (JNIEnv *env, jobject obj){
     return (*env)->NewStringUTF(env,"Hello World,这是夜空中最亮的盖子第一行代码");
  }

Android.mk类似于CMakeLists.txt,用于指明编译方式,源文件名称,模块名称等信息

# Android的路径
LOCAL_PATH := $(call my-dir)
# 清理变量
include $(CLEAR_VARS)
# 模块名称
LOCAL_MODULE    := ndktest-jni
# 源文件,不需要指明头文件,他会自己去找的
LOCAL_SRC_FILES := ndk_test.c
# 编译方式,静态编译还是动态编译
include $(BUILD_SHARED_LIBRARY)

最后在Gradle文件中指明需要编译的Android.mk

android {
    compileSdkVersion 29
    buildToolsVersion "30.0.0"
    defaultConfig {
        applicationId "com.billshen.offerlearn"
        minSdkVersion 15
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
        externalNativeBuild {
            ndkBuild {
                path 'src/main/jni/Android.mk'
            }
        }
    }
}

运行结果

原文地址:https://www.cnblogs.com/billshen/p/13429777.html