Android Studio JNI学习(一)编写一个hello world demo

1 在Android studio中建一个empty project


我这里就叫ndkdemo

2

在java/com/***/ndkdemo中建立一个*.java的源文件,这里随便叫什么,比如NDKTools.java

package com.chys.ndkdemo;

public class NDKTools {
    public static  native String getStringFromNDK();
}

初始化一个native方法。

2 生成.h文件

在终端进入NDKTools.java的目录下使用javac生成头文件

javac -h 目标文件存放的目录 用于生成目标文件的源文件

生成的结果类似这样的


其实也可以自己写,规则如下JNIEXPORT JNICALL保持不变,jstring 是返回类型,Java_com_chys_ndkdemo_NDKTools_getStringFromNDK中Java保持不变,
然后依次是包名,包名中点号用下划线代替,然后是函数名,函数名中如果存在下划线,记得用_1代替,点号用_代替。
JNIEnv代表jni层中某个线程环境,是专用的,可以用env来操作jni函数。

JNIEXPORT jstring JNICALL Java_com_chys_ndkdemo_NDKTools_getStringFromNDK
  (JNIEnv *, jclass);

3 写头文件的实现


新建一个c文件,然后实现相应的代码。这里随便写下就好了。

4. 新建Android.mk文件

    LOCAL_PATH := $(call my-dir)   #当前.h .c文件路径,不用管
    include $(CLEAR_VARS)     #生成文件路径,clear的时候会需要
    LOCAL_MODULE := ndkdemotest-jni      #生成的.so或者.a叫什么,如果这里写lib前缀,生成时候会忽略
    LOCAL_SRC_FILES := ndkdemotest.c      #源文件路径
    include $(BUILD_SHARED_LIBRARY) # 构建包的方式,这里选择动态的
LOCAL_PATH := $(call my-dir):每个Android.mk文件必须以定义开始。它用于在开发tree中查找源文件。宏my-dir则由Build System 提供。返回包含Android.mk目录路径。
include $(CLEAR_VARS) :CLEAR_VARS变量由Build System提供。并指向一个指定的GNU Makefile,由它负责清理很多LOCAL_xxx。例如LOCAL_MODULE,LOCAL_SRC_FILES,LOCAL_STATIC_LIBRARIES等等。但不是清理LOCAL_PATH。这个清理是必须的,因为所有的编译控制文件由同一个GNU Make解析和执行,其变量是全局的。所以清理后才能便面相互影响。
LOCAL_MODULE := ndkdemotest-jni:LOCAL_MODULE模块必须定义,以表示Android.mk中的每一个模块。名字必须唯一且不包含空格。Build System 会自动添加适当的前缀和后缀。例如,demo,要生成动态库,则生成libdemo.so。但请注意:如果模块名字被定义为libabd,则生成libabc.so。不再添加前缀。
LOCAL_SRC_FILES := ndkdemotest.c:这行代码表示将要打包的C/C++源码。不必列出头文件,build System 会自动帮我们找出依赖文件。缺省的C++ 源码的扩展名为.cpp。
include $(BUILD_SHARED_LIBRARY):BUILD_SHARED_LIBRARY是Build System提供的一个变量,指向一个GUN Makefile Script。它负责收集自从上次调用include $(CLEAR_VARS)后的所有LOCAL_xxxxinx。并决定编译什么类型
BUILD_STATIC_LIBRARY:编译为静态库
BUILD_SHARED_LIBRARY:编译为动态库
BUILD_EXECUTABLE:编译为Native C 可执行程序
BUILD_PREBUILT:该模块已经预先编译

5 在NDKTools.java中加入静态初始化

package com.chys.ndkdemo;

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

6 修改app下的build.gradle

plugins {
    id 'com.android.application'
}

android {
    compileSdk 32

    defaultConfig {
        applicationId "com.chys.ndkdemo"
        minSdk 21
        targetSdk 32
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        ndk{
            moduleName "ndkdemotest-jni"
            abiFilters "armeabi-v7a", "arm64-v8a"
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
        externalNativeBuild{
            ndkBuild {
                path 'src/main/jni/Android.mk'
            }
        }
        sourceSets.main{
            jni.srcDirs = []
            jniLibs.srcDirs = ['src/main/jniLibs']
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {

    implementation 'androidx.appcompat:appcompat:1.4.1'
    implementation 'com.google.android.material:material:1.5.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}

7 运行结束

原文链接

posted @   cyssmile  阅读(206)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
历史上的今天:
2021-03-29 windows x64 libyuv编译
2020-03-29 Hough直线检测
2020-03-29 轮廓逼近与拟合
点击右上角即可分享
微信分享提示