NO.2 Android Studio NDK開(kāi)發(fā)全攻略

讀完本章喷面,你可以:

  • 在Android Studio上輕松搭建NDK開(kāi)發(fā)環(huán)境。
  • 掌握最快捷的JNI開(kāi)發(fā)方式。
  • 掌握使用.so文件開(kāi)發(fā)Android程序的技巧昆著。

一、 NDK環(huán)境搭建

  1. 開(kāi)發(fā)工具準(zhǔn)備
    要進(jìn)行Android NDK開(kāi)發(fā)术陶,首先要下載Android NDK開(kāi)發(fā)工具凑懂。可以在AndroidStudio上面下載梧宫,也可以自己下載好了接谨,然后將NDK的路徑設(shè)置為自己下載的Android NDK開(kāi)發(fā)工具的路徑。


    Android Studio中設(shè)置NDK路徑
  2. Gradle的相關(guān)配置
  1. 我們來(lái)配置Project的build.gradle塘匣。
/*gradle插件不支持NDK脓豪,我們需要使用gradle-experimental插件。 */
 dependencies {
        classpath 'com.android.tools.build:gradle-experimental:0.7.0'
    }  
  1. 我們來(lái)配置Module的build.gradle忌卤。
apply plugin: 'com.android.model.application'
model {
    android {
        compileSdkVersion = 23
        buildToolsVersion = "23.0.2"
        defaultConfig {
            applicationId "com.lavor.ndklearning"
            minSdkVersion.apiLevel 15
            targetSdkVersion.apiLevel 23
            versionCode 4
            versionName "1.0.1"
        }
    }
    android.ndk {
        moduleName "lavor"
        ldLibs.addAll(['log'])
        cppFlags.add("-std=c++11")
        cppFlags.add("-fexceptions")
        platformVersion 15
        stl 'gnustl_shared'
    }
    android.buildTypes {
        release {
            minifyEnabled = false
            proguardFiles.add(file("proguard-rules.txt"))
        }
    }
}
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:23.1.1'
    compile 'com.android.support:recyclerview-v7:23.1.1'
    compile 'com.android.support:design:23.1.1'
}  

小提示

  • 首先扫夜,在apply的時(shí)候我們引入的插件名稱由'com.android.application'變成了'com.android.model.application'。
  • 其次驰徊,在原來(lái)android的外層加入了一個(gè)model層次笤闯。
  • 再次,原來(lái)在android的里面的塊棍厂,除了defaultConfig外颗味,全部移除android塊放入model塊中與android并列,并且前面的名字加上android.勋桶。
  • 然后脱衙,compileSdkVersion 23與 buildToolsVersion "23.0.2"改成 compileSdkVersion = 23和 buildToolsVersion = "23.0.2"侥猬,中間加上了=。
  • 其次捐韩,添加上android.ndk塊退唠,塊中的moduleName表示C/C++代碼打包成so文件的名字。
  • 再次荤胁,android.buildTypes塊中的proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'改成proguardFiles.add(file("proguard-rules.txt"))瞧预。
  • 最后,注意dependencies塊依然在最外層仅政,它不在model塊中垢油。

二、 使用NDK開(kāi)發(fā)第一個(gè)JNI程序

  1. 在Android程序中新建一個(gè)包含native(本地)方法的NDKTest類圆丹。
package com.lavor.ndklearning;
public class NDKTest {
            static {
                //加載.so庫(kù)文件
                System.loadLibrary("lavor");
            }
            public native String getString();
}

小知識(shí)

  • 程序中static{}稱為靜態(tài)代碼塊滩愁,它在類初始化的時(shí)候執(zhí)行。不懂請(qǐng)猛擊>>
  1. 將鼠標(biāo)移動(dòng)到方法名getString上辫封,然后按下Alt+Enter快捷鍵硝枉,彈出一些解決的方法建議,點(diǎn)擊第一個(gè)Create Function...


    自動(dòng)生成.c文件
  2. 此時(shí)會(huì)自動(dòng)建立一個(gè)與java目錄同級(jí)的jni目錄倦微,在jni目錄自動(dòng)建立一個(gè)c文件妻味,在c文件中實(shí)現(xiàn)了剛才的native方法。


    .c文件
  3. 然后欣福,稍稍修改一下.c文件中實(shí)現(xiàn)的native方法责球。
JNIEXPORT jstring JNICALL
Java_com_lavor_ndklearning_NDKTest_getString(JNIEnv *env, jobject instance) {
    // TODO
    return (*env)->NewStringUTF(env, "AndroidStudio NDK開(kāi)發(fā)最佳入門實(shí)踐");
}  

補(bǔ)充說(shuō)明

  • 仔細(xì)觀察可以看到c文件的方法名是遵循“Java_包名類名本地方法名”來(lái)組織的(了解到這些后,我們就可以脫離編譯器的幫助拓劝,直接去寫.c文件啦)雏逾。
  1. 最后在Android程序中調(diào)用JNI接口。
public class MainActivity extends Activity {
        private android.widget.TextView text;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            this.text = (TextView) findViewById(R.id.text);
            NDKTest NDK=new NDKTest();
            text.setText(NDK.getString());
        }
}

運(yùn)行程序后界面如下:


運(yùn)行結(jié)果

深度總結(jié)

  • 講道理凿将,我們?cè)谡介_(kāi)發(fā)時(shí)校套,不會(huì)像這樣子去開(kāi)發(fā)。因?yàn)檫@樣的話就會(huì)把我們的c代碼也暴露了出來(lái)牧抵。這明顯與JNI的安全保密機(jī)制相違背,所以侨把,正式開(kāi)發(fā)的時(shí)候犀变,我們會(huì)使用.so文件進(jìn)行全保密式的開(kāi)發(fā)。

三秋柄、 使用.so文件開(kāi)發(fā)Android程序

不知道大家有沒(méi)有記得上一章說(shuō)過(guò)获枝,使用JNI有個(gè)好處就是安全性高,JNI部分的代碼很難被反編譯骇笔。這其實(shí)是要?dú)w功于.so文件省店。下圖為.so文件的生成位置嚣崭。

Android Studio中生成的.so文件位置

具體的使用步驟是怎樣的呢?

  1. 新建一個(gè)Android工程懦傍,命名為:AndroidApplication雹舀。(工程名、包名粗俱、組織名任意)


    一個(gè)隨意的Android工程
  2. 導(dǎo)入.so文件至app/libs中说榆。


    導(dǎo)入.so文件至Android工程
  3. 為了能夠調(diào)用libs文件夾下的.so資源,需在app的build.gradle的android節(jié)點(diǎn)下設(shè)置寸认。
    sourceSets{
        main{
            jniLibs.srcDirs = ['libs']
        }
    }
  1. 新建相關(guān)類結(jié)構(gòu)签财。
package com.lavor.ndklearning;
public class NDKTest {
            static {
                        //加載.so庫(kù)文件
                System.loadLibrary("lavor");
            }
            public native String getString();
}

補(bǔ)充說(shuō)明

  • Android端聲明native code的代碼需要嚴(yán)格按照J(rèn)NI接口來(lái)組織。(也就是說(shuō)偏塞,包名唱蒸、類名都要和.so文件中JNI名稱一致)不懂就點(diǎn)擊這里吧>>
  1. 函數(shù)調(diào)用。
public class DemoActivity extends AppCompatActivity {
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_demo);
                Log.d("NDK",new NDKTest().getString());
            }
}

運(yùn)行結(jié)果如下:


運(yùn)行結(jié)果

注意啦灸叼!此文并非原創(chuàng)油宜,算是對(duì)一波優(yōu)秀文章的總結(jié)吧。筆者希望通過(guò)這種方式激勵(lì)自己學(xué)習(xí)怜姿,也期待可以幫到正在學(xué)習(xí)NDK的你慎冤。歡迎指出本文的BUG,共勉2茁R系獭!5痢披诗!


參考資料

  1. AndroidStudio NDK開(kāi)發(fā)最佳入門實(shí)踐
  2. 如何在Android中使用編譯好的.so庫(kù)
  3. Android Studio NDK及so文件開(kāi)發(fā)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市立磁,隨后出現(xiàn)的幾起案子呈队,更是在濱河造成了極大的恐慌,老刑警劉巖唱歧,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件宪摧,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡颅崩,警方通過(guò)查閱死者的電腦和手機(jī)几于,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)沿后,“玉大人沿彭,你說(shuō)我怎么就攤上這事〖夤觯” “怎么了喉刘?”我有些...
    開(kāi)封第一講書人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵瞧柔,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我睦裳,道長(zhǎng)造锅,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任推沸,我火速辦了婚禮备绽,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘鬓催。我一直安慰自己肺素,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布宇驾。 她就那樣靜靜地躺著倍靡,像睡著了一般。 火紅的嫁衣襯著肌膚如雪课舍。 梳的紋絲不亂的頭發(fā)上塌西,一...
    開(kāi)封第一講書人閱讀 49,772評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音筝尾,去河邊找鬼捡需。 笑死,一個(gè)胖子當(dāng)著我的面吹牛筹淫,可吹牛的內(nèi)容都是我干的站辉。 我是一名探鬼主播,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼损姜,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼饰剥!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起摧阅,我...
    開(kāi)封第一講書人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤汰蓉,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后棒卷,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體顾孽,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年娇跟,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了岩齿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片成畦。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡垢袱,死狀恐怖匿沛,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情吃谣,我是刑警寧澤乞封,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站岗憋,受9級(jí)特大地震影響肃晚,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜仔戈,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一关串、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧监徘,春花似錦晋修、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至户敬,卻和暖如春落剪,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背尿庐。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工忠怖, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人抄瑟。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓凡泣,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親锐借。 傳聞我的和親對(duì)象是個(gè)殘疾皇子问麸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348

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

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,749評(píng)論 25 707
  • 一、NDK產(chǎn)生的背景 Android平臺(tái)從誕生起钞翔,就已經(jīng)支持C严卖、C++開(kāi)發(fā)。眾所周知布轿,Android的SDK基于J...
    Ten_Minutes閱讀 3,485評(píng)論 1 27
  • afinalAfinal是一個(gè)android的ioc哮笆,orm框架 https://github.com/yangf...
    passiontim閱讀 15,408評(píng)論 2 45
  • Android游戲開(kāi)發(fā)實(shí)踐(1)之NDK與JNI開(kāi)發(fā)02 承接上篇Android游戲開(kāi)發(fā)實(shí)踐(1)之NDK與JNI...
    AlphaGL閱讀 3,744評(píng)論 0 24
  • 我對(duì)自己的定位:水, 外柔內(nèi)剛汰扭,水滴石穿稠肘。 我曾溫柔地對(duì)待這個(gè)世界,但是是有所求的萝毛。我患病期間项阴,有段時(shí)間念佛,參與...
    freshriver閱讀 394評(píng)論 0 0