Android Studio中NDK的配置使用示例

使用ndk-build命令手動配置生成so共享庫

正確步驟:首先生成so共享庫,然后再配置到當(dāng)前工程模塊中進行引用

說明:Android Studio 2.2 CMake只支持64位系統(tǒng)(stackflow中詳細(xì)說明)捅位,所以只能使用ndk-build命令手動生成so共享庫(自己32位電腦zaza算途,沒辦法)离熏,CMake方式的可以查看文章后面提供的參考連接突想,同時也提供了谷歌官方的在線參考文檔欠啤。

1. 使用native關(guān)鍵字來聲明本地方法

HelloJni.java

package com.shellever.hellojni;

public class HelloJni {

    // A native method that is implemented by the 'hello-jni' native library (libhello-jni.so)
    public native static String getStringFromJni();
}

2. 使用JDK工具javah命令來自動創(chuàng)建頭文件(.h)

2.1 切換工程面板為Android界面,選擇app目錄右鍵選擇/NEW/Folder/JNI Folder來創(chuàng)建一個jni目錄咽扇,此時會出現(xiàn)一個跟java同級的cpp目錄

javah_new_jni_folder_cpp_android.png

2.2 切換工程面板為Project界面邪财,則會出現(xiàn)一個跟java同級的jni目錄

javah_new_jni_folder_jni_project.png

2.3 使用javah命令來生成頭文件的操作如下:

> cd ./app/src/main/java
> javah -d ../jni com.shellever.hellojni.HelloJni

命令終端Terminal中javah命令詳細(xì)執(zhí)行情況如下:

javah_d_jni.png

執(zhí)行完javah命令后會在jni目錄中生成.h頭文件(com_shellever_hellojni_HelloJni.h):

javah_d_jni_h.png

頭文件內(nèi)容如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_shellever_hellojni_HelloJni */

#ifndef _Included_com_shellever_hellojni_HelloJni
#define _Included_com_shellever_hellojni_HelloJni
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_shellever_hellojni_HelloJni
 * Method:    getStringFromJni
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_shellever_hellojni_HelloJni_getStringFromJni
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

3. 創(chuàng)建源文件并實現(xiàn)頭文件中聲明的方法(.c/.cpp)

切換工程面板至Project界面,并選中/app/src/main/jni目錄质欲,右鍵選擇/NEW/C/C++ Source File來創(chuàng)建一個與頭文件同名的.c源文件(或者.cpp源文件)

javah_new_jni_file_c.png

完整的源文件實現(xiàn)代碼如下:

//
// Created by shellever on 12/16/2016.
//

#include "com_shellever_hellojni_HelloJni.h"

// D:\MySoftware\MyDevelopment\Android\Sdk\ndk-bundle\platforms\android-17\arch-arm\usr\include\jni.h

JNIEXPORT jstring JNICALL Java_com_shellever_hellojni_HelloJni_getStringFromJni
  (JNIEnv *env, jclass clazz)
{
    // In C code
    return (*env)->NewStringUTF(env, "Hello from JNI!");

    // In C++ code
    // return env->NewStringUTF("Hello from JNI!");
}

4. 編寫mk編譯文件

4.1 Android.mk
切換工程面板至Project界面树埠,并選中/app/src/main/jni目錄,右鍵選擇/NEW/File來創(chuàng)建Android.mk編譯文件嘶伟,配置內(nèi)容如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := hello-jni
LOCAL_SRC_FILES := com_shellever_hellojni_HelloJni.c

include $(BUILD_SHARED_LIBRARY)

4.2 Application.mk
切換工程面板至Project界面怎憋,并選中/app/src/main/jni目錄,右鍵選擇/NEW/File來創(chuàng)建Application.mk編譯文件九昧,配置內(nèi)容如下:

# Define the target architecture to be ARM or other.
#APP_ABI := all
#APP_ABI := arm64-v8a armeabi armeabi-v7a mips mips64 x86 x86_64
APP_ABI := arm64-v8a armeabi armeabi-v7a

5. 使用NDK工具ndk-build命令生成so共享庫

使用ndk-build命令來生成頭文件的操作如下:

> cd ../jni
> ndk-build

命令終端Terminal中ndk-build命令詳細(xì)執(zhí)行情況如下:

ndk_build_hello_jni_detail.png

命令ndk-build執(zhí)行成功后會生成與jni同級的libsobj兩個目錄(可以手動刪除掉obj目錄):

ndk_build_hello_jni_folder_file.png

6. 將so共享庫配置到當(dāng)前工程模塊(app)中進行引用

/app/build.gradle配置文件中配置ndk-build命令所生成的so共享庫路徑绊袋,或者直接創(chuàng)建一個jniLibs目錄:/app/src/main/jniLibs/,然后將so庫拷貝到此目錄下即可铸鹰,這樣就不再需要指定libs路徑了癌别。詳細(xì)配置如下:

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"
    defaultConfig {
        applicationId "com.shellever.hellojni"
        minSdkVersion 17
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

        // Specify the shared library
        sourceSets {
            main {
                // 1st step: MUST disable automatic ndk-build call
                jni.srcDirs = []

                // 2nd step: MUST specify the .so path (/app/src/main/libs)
                jniLibs.srcDirs = ['src/main/libs']     // Default: /app/libs
            }
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

另一種libs路徑配置方式:

// Config here
sourceSets.main {
    jni.srcDirs = []    // MUST disable automatic ndk-build call firstly
    jniLibs.srcDir "src/main/libs"      // MUST specify the .so path secondly
}

7. 演示結(jié)果

hello_from_jni.gif

Reference

Android Studio 2.2 更方便地創(chuàng)建JNI項目-CMake
Getting Started with the NDK (Google Official)
googlesamples/android-ndk

源碼參考

HelloJni

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市掉奄,隨后出現(xiàn)的幾起案子规个,更是在濱河造成了極大的恐慌,老刑警劉巖姓建,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件诞仓,死亡現(xiàn)場離奇詭異,居然都是意外死亡速兔,警方通過查閱死者的電腦和手機墅拭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來涣狗,“玉大人谍婉,你說我怎么就攤上這事《频觯” “怎么了穗熬?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長丁溅。 經(jīng)常有香客問我唤蔗,道長,這世上最難降的妖魔是什么窟赏? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任妓柜,我火速辦了婚禮楷扬,結(jié)果婚禮上黎休,老公的妹妹穿的比我還像新娘急前。我一直安慰自己蘸朋,他們只是感情好望浩,可當(dāng)我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布瀑晒。 她就那樣靜靜地躺著清蚀,像睡著了一般泡孩。 火紅的嫁衣襯著肌膚如雪赚瘦。 梳的紋絲不亂的頭發(fā)上最疆,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天,我揣著相機與錄音蚤告,去河邊找鬼努酸。 笑死,一個胖子當(dāng)著我的面吹牛杜恰,可吹牛的內(nèi)容都是我干的获诈。 我是一名探鬼主播,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼心褐,長吁一口氣:“原來是場噩夢啊……” “哼舔涎!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起逗爹,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤亡嫌,失蹤者是張志新(化名)和其女友劉穎嚎于,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體挟冠,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡于购,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了知染。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片肋僧。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖控淡,靈堂內(nèi)的尸體忽然破棺而出嫌吠,到底是詐尸還是另有隱情,我是刑警寧澤掺炭,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布辫诅,位于F島的核電站,受9級特大地震影響涧狮,放射性物質(zhì)發(fā)生泄漏泥栖。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一勋篓、第九天 我趴在偏房一處隱蔽的房頂上張望吧享。 院中可真熱鬧,春花似錦譬嚣、人聲如沸钢颂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽殊鞭。三九已至,卻和暖如春尼桶,著一層夾襖步出監(jiān)牢的瞬間操灿,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工泵督, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留趾盐,地道東北人。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓小腊,卻偏偏與公主長得像救鲤,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子秩冈,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,614評論 2 353

推薦閱讀更多精彩內(nèi)容