色综合图-色综合图片-色综合图片二区150p-色综合图区-玖玖国产精品视频-玖玖香蕉视频

您的位置:首頁技術(shù)文章
文章詳情頁

如何在Android Studio下進(jìn)行NDK開發(fā)

瀏覽:8日期:2022-09-24 10:42:25

在AS中進(jìn)行NDK開發(fā)之前,我們先來簡(jiǎn)單的介紹幾個(gè)大家都容易搞懵的概念:

1. 到底什么是JNI,什么是NDK?

2. 何為“交叉編譯”?

先看什么是JNI?JNI的全稱就是Java Native Interface,即java本地開發(fā)接口。可能大家和我一樣,一聽到接口什么的就犯懵:“我也知道這是java本地開發(fā)接口的意思,但它具體是個(gè)什么意思我還是搞不明白。”其實(shí)JNI它就是一種協(xié)議,一說協(xié)議,那它就是對(duì)某種東西的一個(gè)規(guī)范和約束,說的好聽一點(diǎn)就是標(biāo)準(zhǔn)化。如果你想用我這個(gè)東西,那你必須要遵守我這邊的規(guī)范。像http協(xié)議一樣,http作為超文本傳輸協(xié)議,它規(guī)范了我們上網(wǎng)時(shí)從客戶端到服務(wù)器端等一系列的運(yùn)作流程。正因?yàn)槿绱耍覀儾拍軙惩o阻的上網(wǎng)。那么換做JNI也一樣,只不過JNI這個(gè)協(xié)議是用來溝通java代碼和外部的本地代碼(c/c++)。也就是說有了JNI這個(gè)協(xié)議,我們才能夠隨意的讓java代碼調(diào)用C/C++的代碼,同樣C/C++的代碼也可以調(diào)用java的代碼。如果沒有這個(gè)協(xié)議作為支撐,那么java和C/C++代碼想要相互調(diào)用是不可能的。下面通過兩個(gè)圖簡(jiǎn)單看一下JNI協(xié)議在系統(tǒng)架構(gòu)中處于什么位置:

如何在Android Studio下進(jìn)行NDK開發(fā)

在上圖中,上層綠色的部分一般都是用Java代碼寫的,下層橘黃色的部分一般都是用C/C++代碼寫的。可以看出,正式由于有了中間JNI的存在我們才可以在Application層通過JNI調(diào)用下層中的一些東西。了解了JNI的概念后,我們?cè)倏纯碞DK,NDK(Native Development Kit)就比較好理解了,它就是一個(gè)本地開發(fā)的“工具包”。Java開發(fā)要用到JDK,Android開發(fā)要用到SDK,那我們?cè)贏ndroid中要進(jìn)行native開發(fā),也要用到它對(duì)應(yīng)的工具包,即NDK。通俗的來講,NDK就是幫助我們可以在Android應(yīng)用中使用C/C++來完成特定功能的一套工具。 NDK的作用有很多,我們簡(jiǎn)單的列舉兩個(gè),比如:

1.首先NDK可以幫助開發(fā)者“快速”開發(fā)C(或C++)的動(dòng)態(tài)庫(kù)。

2.其次,NDK集成了“交叉編譯器”。使用NDK,我們可以將要求高性能的應(yīng)用邏輯使用C開發(fā),從而提高應(yīng)用程序的執(zhí)行效率。

上面提到了“交叉編譯”,我們最后再解釋一下什么是交叉編譯。大家都知道編譯器在將中間代碼連接成當(dāng)前計(jì)算機(jī)可執(zhí)行的二進(jìn)制程序時(shí),連接程序會(huì)根據(jù)當(dāng)前計(jì)算機(jī)的CPU、操作系統(tǒng)的類型來轉(zhuǎn)換。而根據(jù)運(yùn)行的設(shè)備的不同,CPU的架構(gòu)也是不同,大體有如下三種常見的CUP架構(gòu):

arm結(jié)構(gòu) :主要在移動(dòng)手持、嵌入式設(shè)備上。我們的手機(jī)幾乎都是使用的這種CUP架構(gòu)。 x86結(jié)構(gòu) : 主要在臺(tái)式機(jī)、筆記本上使用。如Intel和AMD的CPU 。 MIPS架構(gòu):多用在網(wǎng)關(guān)、貓、機(jī)頂盒等設(shè)備。

若想在使用了基于x86架構(gòu)CPU的操作系統(tǒng)上編譯出可以在基于arm結(jié)構(gòu)CPU的操作系統(tǒng)上運(yùn)行的代碼,就必須使用交叉編譯。所以綜上所述:交叉編譯就是在一個(gè)平臺(tái)下(比如:CPU架構(gòu)為X86,操作系統(tǒng)為Windows)編譯出在另一個(gè)平臺(tái)上(比如:CPU架構(gòu)為arm,操作系統(tǒng)為L(zhǎng)inux)可以執(zhí)行的二進(jìn)制代碼。Google提供的NDK就可以完成交叉編譯的工作。

好了,上面的基本概念介紹完以后,我們正式進(jìn)入AS下NDK開發(fā)的講解。

1.首先,你需要把NDK下載下來NDK下載。下載完成后解壓到任意目錄即可(路徑中不要帶有中文字符)。我的就直接放在D盤的ndk目錄下:

如何在Android Studio下進(jìn)行NDK開發(fā)

2.在AS中為你的項(xiàng)目配置NDK。首先新建一個(gè)Android工程JNIDemo,Ctrl + shift + alt + s打開Project Structrue把我們剛才下載好的NDK配置進(jìn)去,點(diǎn)擊OK。

如何在Android Studio下進(jìn)行NDK開發(fā)

3.配置好NDK后,簡(jiǎn)單的為我們的項(xiàng)目布局文件添加一個(gè)TextView和一個(gè)Button,當(dāng)點(diǎn)擊Button的時(shí)候,我們通過調(diào)用底層自己寫好的C/C++代碼來返回一個(gè)字符串,最后呈現(xiàn)在TextView上。activity_main.xml布局代碼:

<?xml version='1.0' encoding='utf-8'?><LinearLayout xmlns:android='http://schemas.android.com/apk/res/android' android:layout_width='match_parent' android:layout_height='match_parent' android:orientation='vertical'> <TextView android: android:layout_width='wrap_content' android:layout_height='wrap_content' android:text='Hello World!' /> <Button android: android:layout_width='match_parent' android:layout_height='wrap_content' android:text='button'/></LinearLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final TextView textview = findViewById(R.id.textview); Button button = findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) {textview.setText(JNIUtils.sayHelloFromJNI()); } }); }}

上面代碼中的JNIUtils.sayHelloFromeJNI()就是我們?cè)谂cMainActivity相同的包中新建JNIUtils類后在里面編寫的native方法。如下所示:

如何在Android Studio下進(jìn)行NDK開發(fā)

可以看到我們上面的sayHelloFromJNI()方法顯示的是警告紅色。把鼠標(biāo)放到上面,它會(huì)提示我們對(duì)應(yīng)的JNI頭文件沒有查找到。那么接下來我們要做的就是去生成與這個(gè)sayHelloFromJNI()方法所對(duì)應(yīng)的頭文件。

4.生成頭文件。快捷鍵alt + F12調(diào)出AS下的Terminal窗口,在Terminal命令行窗口中輸入如下幾條指令,回車:

如何在Android Studio下進(jìn)行NDK開發(fā)

前面兩個(gè)cd命令沒什么好說的,就是先進(jìn)入當(dāng)前項(xiàng)目的app目錄下,然后再進(jìn)入Java目錄下。我們重點(diǎn)說一下最后一條命令:javah -d ../jni com.example.zhangxudong.jindemo.JNIUtils。首先,要生成Java類對(duì)應(yīng)的頭文件我們就必須要用到j(luò)avah這個(gè)命令,其次-d表示生成一個(gè)目錄,那生成一個(gè)什么樣的目錄,具體又在哪里去生成這個(gè)目錄呢?后面的../jni告示了我們。../表示在當(dāng)前目錄的上一層目錄,我們當(dāng)前在Java目錄下,那么它的上層目錄就是main目錄了。而jni就表示我們生成的目錄的名稱。所以整個(gè)../jni就表示在main目錄下生成一個(gè)名為jni的目錄。最后一個(gè)com.example.zhangxudong.jindemo.JNIUtils就是我們?cè)谏厦嫘陆ǖ腏NIUtils的完整類名了。執(zhí)行完這幾天指令后,刷新一下目錄我們就可以在main目錄下看到j(luò)ni這個(gè)目錄,并且在它里面生成了我們JNIUtils類所對(duì)應(yīng)的頭文件。進(jìn)入頭文件中,代碼是如下這個(gè)樣子:

/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class com_example_zhangxudong_jnidemo_JNIUtils */#ifndef _Included_com_example_zhangxudong_jnidemo_JNIUtils#define _Included_com_example_zhangxudong_jnidemo_JNIUtils#ifdef __cplusplusextern 'C' {#endif/* * Class: com_example_zhangxudong_jnidemo_JNIUtils * Method: sayHelloFromJNI * Signature: ()Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_com_example_zhangxudong_jnidemo_JNIUtils_sayHelloFromJNI (JNIEnv *, jclass);#ifdef __cplusplus}#endif#endif

5.頭文件生成以后,我們就需要編寫我們的C/C++代碼了。右鍵jni目錄---->new--->C/C++ Source File

如何在Android Studio下進(jìn)行NDK開發(fā)

輸入要新建的C/C++文件名稱JNIHello,這里我們用C++來編寫,所以Type為.cpp,如果你選擇用C來編寫,那么Type選為.c,點(diǎn)擊ok。這里說一下,在我們進(jìn)行NDK開發(fā)的時(shí)候,選擇用C還是C++,在編寫代碼的時(shí)候除了C和C++基本的語法不同外,還是有許多不同地方需要注意。我們后續(xù)會(huì)慢慢介紹。這里先默認(rèn)跟著我的步驟來。

如何在Android Studio下進(jìn)行NDK開發(fā)

JNIHello.cpp代碼如下:

#include 'com_example_zhangxudong_jnidemo_JNIUtils.h'JNIEXPORT jstring JNICALL Java_com_example_zhangxudong_jnidemo_JNIUtils_sayHelloFromJNI (JNIEnv *env, jclass jclass){return env->NewStringUTF('Hello World From JNI!!!!!');}

可以看到我們首先需要把原來生成的JNIUtlis對(duì)應(yīng)的頭文件引入進(jìn)來,下面的代碼基本都是從com_example_zhangxudong_jnidemo_JNIUtils.h中復(fù)制粘貼過來的一部分,然后稍加修改。修改的地方主要有sayHelloFromJNI的兩個(gè)參數(shù)和里面的簡(jiǎn)單實(shí)現(xiàn),參數(shù)方面就是加了env和jclass兩個(gè)字段。函數(shù)里面的實(shí)現(xiàn)呢,就是簡(jiǎn)單的返回一個(gè)字符串“Hello World From JNI!!!!!”,至于為什么這么寫,我會(huì)在下一篇文章進(jìn)行講解,大家現(xiàn)在就需要知道如果要在這里返回一個(gè)字符串就必須要通過env->NewStringUTF('xxxxxx');這行代碼。

6.上面的搞定以后,我們需要在app的build.gradle中的defaultConfig中加入如下代碼。它表示項(xiàng)目在編譯時(shí)生成的動(dòng)態(tài)庫(kù)的名字。

如何在Android Studio下進(jìn)行NDK開發(fā)

最后,我們還需在JNIUitls中加載我們生成的動(dòng)態(tài)庫(kù):

public class JNIUtils { static { System.loadLibrary('JNIHello'); } public static native String sayHelloFromJNI();}

我們把加載動(dòng)態(tài)庫(kù)的代碼放到靜態(tài)代碼塊中,就是表示在JNIUtils這個(gè)類在加載的時(shí)候就去加載我們的動(dòng)態(tài)庫(kù)。

7.經(jīng)過上面的5步,關(guān)于如何在AS中進(jìn)行簡(jiǎn)單的NDK所需要的步驟差不多就講完了。不過還有最后一點(diǎn)需要注意。到這里我們基本就可以執(zhí)行一下我們的項(xiàng)目了,現(xiàn)在運(yùn)行一下項(xiàng)目試一試......不出意外的話項(xiàng)目是build不成功的,它會(huì)報(bào)如下的錯(cuò)誤:

Error:Execution failed for task ’:app:compileDebugNdk’.> Error: Flag android.useDeprecatedNdk is no longer supported and will be removed in the next version of Android Studio. Please switch to a supported build system.Consider using CMake or ndk-build integration. For more information, go to:https://d.android.com/r/studio-ui/add-native-code.html#ndkCompileTo get started, you can use the sample ndk-build script the Androidplugin generated for you at:E:JNIDemoappbuildintermediatesndkdebugAndroid.mkAlternatively, you can use the experimental plugin:https://developer.android.com/r/tools/experimental-plugin.htmlTo continue using the deprecated NDK compile for another 60 days, set android.deprecatedNdkCompileLease=1515317190556 in gradle.properties

因?yàn)槲疫@里用的是Android Studio3.0,報(bào)出的這個(gè)錯(cuò)誤很可能和原來版本的AS不同,以前出現(xiàn)類似錯(cuò)誤的時(shí)候,我們的解決方案一般都是在gradle.properties中添加一行這樣的代碼:android.useDeprecatedNdk=true就搞定了。但是AS換為3.0后你可以再試一下這種方案,肯定是不行的,它會(huì)提示你“Flag android.useDeprecatedNdk is no longer supported and will be removed in the next version of Android Studio. Please switch to a supported build system.”大體意思就是最新的AS已經(jīng)不支持useDeprecatedNdk這個(gè)標(biāo)記了,并且在后續(xù)版本的AS中,它將被移除。所以我們新的解決方案就是按照它的提示在gradle.properties中添家android.deprecatedNdkCompileLease=1515317190556這行代碼。

最后我們運(yùn)行一下項(xiàng)目,點(diǎn)擊button,效果如下。可以看到,我們成功的通過java代碼調(diào)用了C++的代碼,并返回Hello World From JNI!!!!!這個(gè)字符串。

如何在Android Studio下進(jìn)行NDK開發(fā)

那我們生成的動(dòng)態(tài)庫(kù)(.so文件)都在哪里呢?點(diǎn)開app--->build--->intermediates--->ndk--->debug--->libs,可以看到各個(gè)平臺(tái)對(duì)應(yīng)的動(dòng)態(tài)庫(kù)都已經(jīng)生成了。

如何在Android Studio下進(jìn)行NDK開發(fā)

到此這篇關(guān)于如何在Android Studio下進(jìn)行NDK開發(fā)的文章就介紹到這了,更多相關(guān)Android Studio下NDK開發(fā)內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Android
相關(guān)文章:
主站蜘蛛池模板: 久久久久久毛片免费观看 | 国产综合精品在线 | 国产亚洲综合久久 | 在线毛片一区二区不卡视频 | 国产男女猛烈无遮档免费视频网站 | 国产一区二区三区毛片 | 国产日本欧美高清免费区 | 久久精品免费i 国产 | 久久国产精品女 | 99免费在线观看视频 | 国产日韩精品一区二区在线观看 | 香港日本韩国三级网站 | 色偷偷成人 | 男人的亚洲天堂 | 国产在线精品成人一区二区三区 | 三级毛片在线免费观看 | 亚洲视频在线免费观看 | 亚洲精品视频区 | 91理论片午午伦夜理片久久 | 大胆gogo999亚洲肉体艺术 | 久久精品国产99精品最新 | 久久在现 | 国产成人高清精品免费5388密 | 免费高清毛片在线播放视频 | 精品一区二区三区免费观看 | 国产精品二区高清在线 | 亚欧视频在线观看 | 日本香蕉一区二区三区 | 欧美精品久久久亚洲 | 亚洲精品15p | 精品国产一区二区三区国产馆 | 好看的看黄a大片爽爽影院 好男人天堂网 | 亚洲 欧美 激情 另类 自拍 | 久久久久综合给合狠狠狠 | 免费人成年短视频在线观看网站 | 国产精品va一级二级三级 | 成人免费大片黄在线观看com | 久久机热综合久久国产 | 国产亚洲欧美精品久久久 | 国产视频二 | 在线播放高清国语自产拍免费 |