android 串口開發第一篇:搭建ndk開發環境以及第一個jni調用程序

一:ndk環境搭建

     1:開發環境

  我使用的是android studio 2.3.3版本,搭建ndk開發環境比較簡單,打開File----Settings----Appearance&Behavior----System  Settings----Android SDK,選擇SDK Tools,將CMake,LLDB,NDK 前的複選框勾上,點擊Apply,而後就是等待ndk下載完成。html

  安裝成功後,右鍵項目----open  module setting,Android NDK location會自動賦值java

  

 二:第一個jni程序

     1:建立ndk項目

      建立ndk項目和普通android項目有一點區別,須要把Include C++ support前面的複選框勾上,而後直接下一步。但在最後一步,有一個c++下拉框選項,能夠根據你的實際狀況適當修改,C++ Standard :點擊下拉框,能夠選擇標準 C++,或者選擇默認 CMake 設置的 Toolchain Default 選項。Exceptions Support :若是你想使用有關 C++ 異常處理的支持,就勾選它。勾選以後,Android Studio 會在 module 層的 build.gradle 文件中的 cppFlags 中添加 -fexcetions 標誌。Runtime Type Information Support :若是你想支持 RTTI,那麼就勾選它。勾選以後,Android Studio 會在 module 層的 build.gradle 文件中的 cppFlags 中添加 -frtti 標誌。android

                                                          

     項目建立好後,app下多了一個cpp目錄,該目錄用於存放c程序的源碼,頭文件,預編譯項目等,android studio 會默認幫咱們建立一個native-lib.cpp文件,該文件已有一個測試方法,結構圖以下:c++

  

      經過上圖看到,在External Build Files 下面多了一個CMakeLists.txt文件,該文件用於c程序須要生成so文件的配置文件。編程

  cmake_minimum_required(VERSION 3.4.1):這是版本信息,咱們不用管它app

  add_library():這個命令是,經過add.library()定義多個庫,CMake會去自動構建他們,一個*.cpp文件對應一個add_library命令.ide

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文件名稱
             src/main/cpp/native-lib.cpp )

  find_library():定位 NDK library 的位置,並將其位置存儲在一個變量之中。在構建腳本的其餘地方使用這個變量,來代指 NDK library。下面的示例代碼將 Android-specific log support library 的位置存儲到變量 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 )

  如今咱們來看native-lib.cpp文件,這是as幫咱們自動生成好的,返回是一個Hello from C++的字符串。gradle

#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表明返回值, 參數JNIEnv* env,表明指針,jobject 表明調用這個方法的對像(普通方法是jobject,靜態方法是jclass)後面的參數和java類中定義的本地方法對數相對應,方法命名規則:Java_包名_調用jni方法的類名_方法名,android studio 幫咱們
生成的程序,activity包名是serialport.com.ndkjnidemo,類名是MainActivity,方法名是stringFromJNI,因此native-lib.cpp方法名稱爲:Java_serialport_com_ndkjnidemo_MainActivity_stringFromJNI,其中返回值類型和java數據類型對應以下

    若是咱們須要寫多個jni方法,*.cpp格式以下:ui

//方法一
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"//若是不寫extern "C" java是沒法調用到這裏定義的方法
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());
}

  最後咱們來看自動生成的MainActivity,在onCreate中調用stringFromJNI,而後給文本組件賦值,軟件運行參見圖一

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值來自,CMakeLists.txt文件中,add_library命令的第一個參數 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自動自成的,因此此處不上傳代碼,demo運行結果:  

 

參考文章:

Android NDK 開發(五)AndroidStudio 2.2 NDK的開發環境搭建

一天掌握Android JNI本地編程 快速入門

相關文章
相關標籤/搜索