android串口開(kāi)發(fā)入門(mén)之搭建ndk開(kāi)發(fā)環(huán)境及第一個(gè)jni調(diào)用程序
前言
這幾天專(zhuān)門(mén)研究了下JNI編程,在網(wǎng)上找了好多資料,不過(guò)好多都是以前的,沒(méi)有更新,而且有的還是錯(cuò)誤的,讓人不得不吐槽一把。所以覺(jué)得自己來(lái)一篇,本文將詳細(xì)介紹關(guān)于android搭建ndk開(kāi)發(fā)環(huán)境及第一個(gè)jni調(diào)用程序的相關(guān)內(nèi)容,分享出來(lái)供大家參考學(xué)習(xí),下面話不多說(shuō)了,來(lái)一起看看詳細(xì)的介紹吧。
一:ndk環(huán)境搭建
1:開(kāi)發(fā)環(huán)境
我使用的是android studio 2.3.3版本,搭建ndk開(kāi)發(fā)環(huán)境比較簡(jiǎn)單,打開(kāi)File----Settings----Appearance&Behavior----System Settings----Android SDK,選擇SDK Tools,將CMake,LLDB,NDK 前的復(fù)選框勾上,點(diǎn)擊Apply,然后就是等待ndk下載完成。
安裝成功后,右鍵項(xiàng)目----open module setting,Android NDK location會(huì)自動(dòng)賦值
二:第一個(gè)jni程序
1:創(chuàng)建ndk項(xiàng)目
創(chuàng)建ndk項(xiàng)目和普通android項(xiàng)目有一點(diǎn)區(qū)別,需要把Include C++ support前面的復(fù)選框勾上,然后直接下一步。但在最后一步,有一個(gè)c++下拉框選項(xiàng),可以根據(jù)你的實(shí)際情況適當(dāng)修改,C++ Standard :點(diǎn)擊下拉框,可以選擇標(biāo)準(zhǔn) C++,或者選擇默認(rèn) CMake 設(shè)置的 Toolchain Default 選項(xiàng)。Exceptions Support :如果你想使用有關(guān) C++ 異常處理的支持,就勾選它。勾選之后,Android Studio 會(huì)在 module 層的 build.gradle 文件中的 cppFlags 中添加 -fexcetions 標(biāo)志。Runtime Type Information Support :如果你想支持 RTTI,那么就勾選它。勾選之后,Android Studio 會(huì)在 module 層的 build.gradle 文件中的 cppFlags 中添加 -frtti 標(biāo)志。
項(xiàng)目創(chuàng)建好后,app下多了一個(gè)cpp目錄,該目錄用于存放c程序的源碼,頭文件,預(yù)編譯項(xiàng)目等,android studio 會(huì)默認(rèn)幫我們創(chuàng)建一個(gè)native-lib.cpp文件,該文件已有一個(gè)測(cè)試方法,結(jié)構(gòu)圖如下:
通過(guò)上圖看到,在External Build Files 下面多了一個(gè)CMakeLists.txt文件,該文件用于c程序需要生成so文件的配置文件。
cmake_minimum_required(VERSION 3.4.1):這是版本信息,我們不用管它
add_library():這個(gè)命令是,通過(guò)add.library()定義多個(gè)庫(kù),CMake會(huì)去自動(dòng)構(gòu)建他們,一個(gè)*.cpp文件對(duì)應(yīng)一個(gè)add_library命令.
add_library( # Sets the name of the library.生成so文件的名字,建議和cpp文件同名 native-lib # Sets the library as a shared library. SHARED # Provides a relative path to your source file(s). 需要生成so文件的cpp文件名稱(chēng) src/main/cpp/native-lib.cpp )
find_library():定位 NDK library 的位置,并將其位置存儲(chǔ)在一個(gè)變量之中。在構(gòu)建腳本的其他地方使用這個(gè)變量,來(lái)代指 NDK library。下面的示例代碼將 Android-specific log support library 的位置存儲(chǔ)到變量 log-lib 中
find_library( # Sets the name of the path variable. log-lib # Specifies the name of the NDK library that # you want CMake to locate. log )
現(xiàn)在我們來(lái)看native-lib.cpp文件,這是as幫我們自動(dòng)生成好的,返回是一個(gè)Hello from C++的字符串。
#include <jni.h> #include <string> extern "C" JNIEXPORT jstring JNICALL Java_serialport_com_ndkjnidemo_MainActivity_stringFromJNI( JNIEnv* env, jobject /* this */) { std::string hello = "Hello from C++"; return env->NewStringUTF(hello.c_str()); }
JNIEXPORT jstring JNICALL 這里的jstring代表返回值, 參數(shù)JNIEnv* env,代表指針,jobject 代表調(diào)用這個(gè)方法的對(duì)像(普通方法是jobject,靜態(tài)方法是jclass)后面的參數(shù)和java類(lèi)中定義的本地方法對(duì)數(shù)相對(duì)應(yīng),方法命名規(guī)則:Java_包名_調(diào)用jni方法的類(lèi)名_方法名,android studio 幫我們生成的程序,activity包名是serialport.com.ndkjnidemo,類(lèi)名是MainActivity,方法名是stringFromJNI,所以native-lib.cpp方法名稱(chēng)為Java_serialport_com_ndkjnidemo_MainActivity_stringFromJNI,其中返回值類(lèi)型和java數(shù)據(jù)類(lèi)型對(duì)應(yīng)如下
如果我們需要寫(xiě)多個(gè)jni方法,*.cpp格式如下:
//方法一 extern "C" JNIEXPORT jstring JNICALL Java_serialport_com_ndkjnidemo_MainActivity_test1( JNIEnv* env, jobject /* this */) { std::string hello = "Hello from C++"; return env->NewStringUTF(hello.c_str()); } //方法二 extern "C"http://如果不寫(xiě)extern "C" java是無(wú)法調(diào)用到這里定義的方法 JNIEXPORT jstring JNICALL Java_serialport_com_ndkjnidemo_MainActivity_test2( JNIEnv* env, jobject /* this */) { std::string hello = "Hello from C++"; return env->NewStringUTF(hello.c_str()); }
最后我們來(lái)看自動(dòng)生成的MainActivity,在onCreate中調(diào)用stringFromJNI,然后給文本組件賦值,軟件運(yùn)行參見(jiàn)圖一
package serialport.com.ndkjnidemo;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.widget.TextView;public class MainActivity extends AppCompatActivity { static { //native-lib值來(lái)自,CMakeLists.txt文件中,add_library命令的第一個(gè)參數(shù) System.loadLibrary("native-lib"); } protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView tv = (TextView) findViewById(R.id.sample_text); tv.setText(stringFromJNI());}public native String stringFromJNI(); }
代碼都是android studio自動(dòng)自成的,所以此處不上傳代碼,demo運(yùn)行結(jié)果:
參考文章:
Android NDK 開(kāi)發(fā)(五)AndroidStudio 2.2 NDK的開(kāi)發(fā)環(huán)境搭建
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
android開(kāi)發(fā)教程之間隔執(zhí)行程序(android計(jì)時(shí)器)
android開(kāi)發(fā)中有些情況需要隔一段時(shí)間去執(zhí)行某個(gè)操作一次或者是每隔一段時(shí)間久執(zhí)行某個(gè)操作,下面是實(shí)現(xiàn)方法2014-02-02Android onKeyDown監(jiān)聽(tīng)返回鍵無(wú)效的解決辦法
這篇文章主要介紹了 Android onKeyDown監(jiān)聽(tīng)返回鍵無(wú)效的解決辦法的相關(guān)資料,需要的朋友可以參考下2017-06-06Android實(shí)現(xiàn)可輸入數(shù)據(jù)的彈出框
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)可輸入數(shù)據(jù)的彈出框,文章提供了兩種方式,示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-01-01淺談Android應(yīng)用內(nèi)懸浮控件實(shí)踐方案總結(jié)
本篇文章主要介紹了淺談Android應(yīng)用內(nèi)懸浮控件實(shí)踐方案總結(jié),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-11-11Android中Bitmap常見(jiàn)的一些操作:縮放、裁剪、旋轉(zhuǎn)和偏移
Bitmap是Android中處理圖片的一個(gè)重要的類(lèi),下面這篇文章主要給大家介紹了關(guān)于Android中Bitmap常見(jiàn)的一些操作:縮放、裁剪、旋轉(zhuǎn)和偏移的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2018-07-07Android仿QQ空間主頁(yè)面的實(shí)現(xiàn)
今天模仿安卓QQ空間,打開(kāi)程序的啟動(dòng)畫(huà)面和導(dǎo)航頁(yè)面我就不做了,大家可以模仿微信的那個(gè)做一下,很簡(jiǎn)單。這次主要做一下主頁(yè)面的實(shí)現(xiàn),感興趣的朋友可以參考下2013-01-01Android項(xiàng)目中g(shù)radle的執(zhí)行流程
大家好,本篇文章主要講的是Android項(xiàng)目中g(shù)radle的執(zhí)行流程,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下2022-01-01Android 改變圖標(biāo)原有顏色和搜索框的實(shí)例代碼
讓Android也能有iOS那么方便的圖片色調(diào)轉(zhuǎn)換,就像同一個(gè)圖標(biāo),但是有多個(gè)地方使用,并且顏色不一樣,就可以用這個(gè)方法了。 本文實(shí)現(xiàn)TextView圖片和文字居中,鍵盤(pán)搜索功能,具體實(shí)現(xiàn)代碼大家跟隨腳本之家小編看看吧2017-09-09