NDK開發(fā)—Hello World

開始嘗試NDK開發(fā)
圖片用的自己的Github圖床,好像會出現(xiàn)無法識別,看不了的可以轉(zhuǎn)github NDK開發(fā)—Hello World

前言廢語

關(guān)于NDK和JNI的概念介紹,網(wǎng)上一搜一麻袋就不做介紹了,站在初學(xué)者的角度,我們可以簡單的這樣李姐:

  • NDK(Native develop kit)就是一套工具,能夠使用C/C++語言來實(shí)現(xiàn)部分功能。。

  • JNI(Java Native Interface)一種接口約定,滿足java和C/C++之間的相互調(diào)用。

當(dāng)然這里面有很多內(nèi)容,比如JavaVM、JNIEnv、JNI原理等等,這些對于初學(xué)者都不重要,我也不懂,先會用,再深入吧。

環(huán)境配置

這一節(jié)可以參考官方教程向您的項(xiàng)目添加 C 和 C++ 代碼

  • Android studio版本 Bumblebee

  • NDK版本 20+

  1. sdk manager中安裝NDK和CMake

[站外圖片上傳中...(image-71e18-1662220675755)]

  1. Project Structure 中指定NDK路徑,如果說沒有,按照提示下載即可。

[站外圖片上傳中...(image-449825-1662220675755)]

  • 下載結(jié)束后Apply時如果提示NDK does not contain any platforms,自己到相應(yīng)的路徑下面新建一個名為platforms的目錄文件。

  • 注意到local.properties文件中確認(rèn)是否有ndk.dir

開始打代碼

編寫C相關(guān)的代碼

  1. 新建一個NDKTools類文件,內(nèi)如如下,加上native修飾符,表示這個方法是native實(shí)現(xiàn)。
package com.jiajia.mypractisedemos.module.ndk;

/**
 * Created by Numen_fan on 2022/9/1
 * Desc:
 **/
public class NDKTools {

    public static native String getStringFromNDK();

}
  1. 進(jìn)行項(xiàng)目的編譯,就是build一下,生成NDKTools.class文件。這個class文件在/app/build/intermediates/javac/debug/classes目錄下。
  2. 終端進(jìn)入到/app/build/intermediates/javac/debug/classes目錄,執(zhí)行如下命令。
javah -jni com.jiajia.mypractisedemos.module.ndk.NDKTools

注意前面拼上完整的包名,這里我嘗試進(jìn)入到ndk目錄下,然后執(zhí)行javah -jni NDKTools,提示失敗。

  1. 執(zhí)行完之后,會在/app/build/intermediates/javac/debug/classes下生成一個.h的頭文件;內(nèi)容如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_jiajia_mypractisedemos_module_ndk_NDKTools */

#ifndef _Included_com_jiajia_mypractisedemos_module_ndk_NDKTools
#define _Included_com_jiajia_mypractisedemos_module_ndk_NDKTools
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_jiajia_mypractisedemos_module_ndk_NDKTools
 * Method:    getStringFromNDK
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_jiajia_mypractisedemos_module_ndk_NDKTools_getStringFromNDK
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif
  • 還記得.h文件在C語言中的角色嗎?其實(shí)就是函數(shù)聲明拉。
  • 注意看第一行,提示我們不要擅自編輯呢。
  1. 新建jni目錄,如果你的項(xiàng)目沒有jni目錄,按照下面的方式新建,不要New -> Package
    [站外圖片上傳中...(image-1f505e-1662220675755)]
    這樣新建的jni目錄,會在app的build.gradle中自動添加如下配置
sourceSets {
        main {
            jni {
                srcDirs 'src/main/jni'
            }
        }
    }
  1. 將剛才生成的.h聲明文件,移動到j(luò)ni目錄下。
  2. 在jni目錄下新建一個C語言文件ndkdemotest.c,編寫代碼如下
#include "com_jiajia_mypractisedemos_module_ndk_NDKTools.h"

JNIEXPORT jstring JNICALL Java_com_jiajia_mypractisedemos_module_ndk_NDKTools_getStringFromNDK  (JNIEnv *env, jclass obj) {
    return (*env) -> NewStringUTF(env, "我是JNI的Hello World啊");  
}
  • 注意第一行,需要將剛才的.h聲明文件引入。
  • NewStringUTF是啥,不重要,先知道他返回了一個字符串就行。
  1. 同在jni目錄下新建Android.mk文件,寫上如下內(nèi)容
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := ndkdemotest-jni

LOCAL_SRC_FILES := ndkdemotest.c

include $(BUILD_SHARED_LIBRARY)
  • 關(guān)于各個字段的含義,可以找些資料看一下,我還沒搞懂。大體意思就是一些配置,來生成產(chǎn)物。
  • 注意LOCAL_SRC_FILES,這個應(yīng)該就是指定要編譯的C文件;TODO:如果需要編譯多個C文件呢?
  • LOCAL_MODULE 應(yīng)該就是指定產(chǎn)物的名稱,xxxx.so ?
  1. 在app的build.gradle中添加如下兩處配置。
android {
  defaultConfig {
    ……
    ndk{   // 1
            moduleName "ndkdemotest-jni"
            abiFilters "arm64-v8a", "armeabi-v7a"
        }
  }
  externalNativeBuild {  // 2
        ndkBuild {
            path 'src/main/jni/Android.mk'
        }
    }
  ……
}
  1. 在代碼中l(wèi)oad產(chǎn)物,我就寫在NDKTools類中。
static {        
      System.loadLibrary("ndkdemotest-jni");    
}

到這里,C相關(guān)的編碼和配置就完成了,這時候可以跑一下代碼,看看會不會報錯,如果報錯的話,就網(wǎng)上找找辦法如何解決。

編寫Android層代碼

  1. Android層的代碼就很簡單了。
String text = NDKTools.getStringFromNDK();
((TextView)findViewById(R.id.tv_ndk_string)).setText(text);
  1. 運(yùn)行效果
    [站外圖片上傳中...(image-65f270-1662221046008)]

參考資料

  1. http://www.itdecent.cn/p/b4431ac22ec2?!局攸c(diǎn)參考的文章】

  2. http://www.itdecent.cn/p/87ce6f565d37

  3. https://developer.android.com/studio/projects/add-native-code?hl=zh-cn

  4. https://blog.csdn.net/qq_33221533/article/details/113173396

  5. https://blog.csdn.net/weixin_37639900/article/details/99866131

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容