Android Studio NDK開發(fā)(二):Welcome to JNI

前言

現(xiàn)在我們從零開始NDK開發(fā)早歇,本篇博客將介紹如何創(chuàng)建一個native方法,并在Activity中調(diào)用。如果大家對于NDK開發(fā)的配置不了解的話,可以查看:
Android Studio NDK開發(fā)(一):NDK開發(fā)準(zhǔn)備工作(CMake方式)

Welcome to JNI

1.新建c文件

這里我們不使用Android Studio默認(rèn)創(chuàng)建的C/C++文件native-lib.cpp沾歪,鼠標(biāo)點擊cpp文件夾(如果沒有可在main文件夾下新建),右擊new -> C/C++ Source File雾消,輸入文件名zhangpan(可自定義)灾搏,type我選的是.c,點擊ok立润,然后就可以看見cpp文件夾下生成了zhangpan.c文件狂窑,此時該文件頂部是有提示文字的,提醒你去配置CMakeLists桑腮。

2.配置CMakeLists.txt

在CMakeList(如果沒有可在app下新建)中添加:

add_library( # Sets the name of the library.
             zhangpan

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             src/main/cpp/zhangpan.c)
target_link_libraries( # Specifies the target library.
                       zhangpan

                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib} )

點擊Snyc Now泉哈,以上就將添加了自己寫的庫,并將自己的庫與NDK中的庫進行連接破讨。

3.配置build.gradle

如果新建工程的時候丛晦,已經(jīng)勾選了include C/C++ support,這里就已經(jīng)生成了添忘,可跳過采呐。如果沒有,可在app下的build.gradle如下添加搁骑。
在android下defaultConfig下添加:

externalNativeBuild {
            cmake {
                //默認(rèn)是cppFlags ""
                //如果要修改Customize C++ support部分,可在這里加入
                cppFlags ""
            }
        }

再在android下添加:

externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }
    }

4.native方法的聲明

我在MainActity中聲明了一個native方法(可自定義)

public native String getStringFromJNI();

這里我做的就是Java中調(diào)用C的函數(shù)又固,從而返回一個字符串仲器,并展示在界面中。
光標(biāo)定位在getStringFromJNI中仰冠,Alt + Enter選中第一個乏冀,創(chuàng)建native函數(shù)。

#include "jni.h"
#include <stdlib.h>

JNIEXPORT jstring JNICALL
Java_com_zhangpan_myjnicmake_MainActivity_getStringFromJNI(
    JNIEnv *env,
    jobject jobj) {
    //JNIEnv 結(jié)構(gòu)體指針
    //env二級指針(對應(yīng)c洋只,在C++是一個結(jié)構(gòu)體的一級指針)辆沦,由于需要用到JNIEnv變量,而JNIEnv是結(jié)構(gòu)體指針识虚,需要一個變量來表示JNIEnv肢扯,所以這個變量就是二級指針,而C++中有this關(guān)鍵字的担锤,直接可以表示
    //每個native函數(shù)蔚晨,都至少有兩個參數(shù)(JNIEnv*,jclass或者jobject)
    //1.當(dāng)native方法為靜態(tài)方法時肛循,jclass代表native方法所屬類的class對象(MainActivity.class)
    //2.當(dāng)native方法為非靜態(tài)方法時铭腕,jobject代表native方法所屬類的對象
    return (*env)->NewStringUTF(env, "Welcome to JNI");
}

注意:
(以下所述银择,方法代表Java中的方法,函數(shù)代表C/C++中的函數(shù))
1.添加頭文件jni.h(用于關(guān)聯(lián)Java和C/C++)和stdlib.h
2.JNIEXPORT jstring JNICALL中jstring是函數(shù)的返回值累舷,其余兩個可不用管浩考,類似于Java中的關(guān)鍵字作用。
3.點擊參數(shù)中的JNIEnv進入jni.h中被盈,可以看出JNIEnv是一個結(jié)構(gòu)體指針析孽,因此env就是一個二級指針,記住這里是C的代碼害捕,如果是C++绿淋,這里的env只是一個結(jié)構(gòu)體的一級指針。有人可能會問尝盼,為什么在C和C++中會不一樣呢吞滞,這是因為C++中已經(jīng)有了this關(guān)鍵字了,而C中是不存在的盾沫,而這里又需要用到JNIEnv的變量裁赠,所以為了表示它,在C中就有了env這個二級指針赴精。其實C++中雖然傳入了this關(guān)鍵字佩捞,但是其函數(shù)內(nèi)部還是調(diào)用了C的代碼,也就是說C++在C的基礎(chǔ)上還封裝了一層蕾哟。
4.每個native函數(shù)都至少有兩個參數(shù)JNIEnv*一忱,jclass或者jobject。
5.當(dāng)native方法為靜態(tài)方法時谭确,jclass代表native方法所屬類的class對象(MainActivity.class)帘营;
當(dāng)native方法為非靜態(tài)方法時,jobject代表native方法所屬類的對象逐哈。

5.MainActivity

添加靜態(tài)代碼塊芬迄,加載自己寫的庫,調(diào)用并展示在TextView中昂秃。

/**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    public native String getStringFromJNI();
    
    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("zhangpan");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        TextView tv = (TextView) findViewById(R.id.sample_text);
        tv.setText(getStringFromJNI());
    }

點擊運行

1.png

展望

Welcome to JNI已經(jīng)完成禀梳,也知道了Java是如何調(diào)用C/C++中的函數(shù)的,但是我們是不是存在疑問肠骆,比如jstring到底是什么算途,C/C++怎樣訪問Java中的屬性和方法呢?請看接下來的博客哗戈。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末郊艘,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子纱注,更是在濱河造成了極大的恐慌畏浆,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件狞贱,死亡現(xiàn)場離奇詭異刻获,居然都是意外死亡,警方通過查閱死者的電腦和手機瞎嬉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進店門蝎毡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人氧枣,你說我怎么就攤上這事沐兵。” “怎么了便监?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵扎谎,是天一觀的道長。 經(jīng)常有香客問我烧董,道長毁靶,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任逊移,我火速辦了婚禮预吆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘胳泉。我一直安慰自己拐叉,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布扇商。 她就那樣靜靜地躺著巷嚣,像睡著了一般。 火紅的嫁衣襯著肌膚如雪钳吟。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天窘拯,我揣著相機與錄音红且,去河邊找鬼。 笑死涤姊,一個胖子當(dāng)著我的面吹牛暇番,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播思喊,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼壁酬,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起舆乔,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤岳服,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后希俩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體吊宋,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年颜武,在試婚紗的時候發(fā)現(xiàn)自己被綠了璃搜。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡鳞上,死狀恐怖这吻,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情篙议,我是刑警寧澤唾糯,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站涡上,受9級特大地震影響趾断,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜吩愧,卻給世界環(huán)境...
    茶點故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一芋酌、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧雁佳,春花似錦脐帝、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至星澳,卻和暖如春疚顷,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背禁偎。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工腿堤, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人如暖。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓笆檀,卻偏偏與公主長得像,于是被迫代替她去往敵國和親盒至。 傳聞我的和親對象是個殘疾皇子酗洒,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,527評論 2 349