1. 程式人生 > >Android Studio向專案新增C/C++原生程式碼教程

Android Studio向專案新增C/C++原生程式碼教程

Android Studio向專案新增C/C++原生程式碼教程

 轉自:http://www.cnblogs.com/lsdb/p/9337285.html

說明:本文相當於官方文件的個人重新實現,官方文件連結:https://developer.android.com/studio/projects/add-native-code

向專案新增C/C++程式碼分為兩種情況,一種是建立支援C/C++程式碼的新專案,一種是向原先不支援C/C++的已有專案新增C/C++程式碼。這兩種情況分別對應本教程的第一大點和第二大點。

 

一、建立支援C/C++原生程式碼的新專案教程

1.1、下載NDK和構建工具

要為應用編譯和除錯原生程式碼,需要安裝以下元件:

Android原生開發工具包 (NDK)----這套工具集允許我們為Android使用C和C++程式碼,且其提供眾多平臺庫讓我們可以管理原生Activity和訪問物理裝置元件,例如感測器和觸控輸入。

CMake----一款外部構建工具,可與Gradle搭配使用來構建原生庫。如果只計劃使用ndk-build,則不需要此元件。

LLDB----一種除錯程式,Android Studio使用它來除錯原生程式碼。

安裝步驟如下:

選單欄----Tools----SDK Manager

SDK Tools----鉤選CMake/LLDB/NDK三項----點選確定

 

檔案比較大,大概需要一二十分鐘(受網速影響),完成後點選“Finish”即可

 

 

1.2、建立支援C/C++的新專案

選單欄--File---new---New Project

其他資訊按自己的需要填,主要是鉤選“Include C++ support”

接下來的三步和正常的專案建立沒什麼區,按自己的需要鉤選或填寫即可。我這裡演示使用,全直接使用預設配置。

在嚮導最後“Customize C++ Support”會有以下幾項內容:

C++ Standard----使用下拉列表選擇您希望使用哪種 C++ 標準。選擇 Toolchain Default 會使用預設的 CMake 設定。

Exceptions Support----如果您希望啟用對 C++ 異常處理的支援,請選中此複選框。如果啟用此複選框,Android Studio 會將 -fexceptions 標誌新增到模組級 build.gradle 檔案的 cppFlags 中,Gradle 會將其傳遞到 CMake。

Runtime Type Information Support----如果您希望支援 RTTI,請選中此複選框。如果啟用此複選框,Android Studio 會將 -frtti 標誌新增到模組級build.gradle 檔案的 cppFlags 中,Gradle 會將其傳遞到 CMake。

我這裡使用預設配置,直接點選“Finish”

 

1.3、確認程式可以成功呼叫C++函式

將專案切換到“Android”檢視觀察整個專案,可發現較沒有“Include C++ support”的專案,多了cpp和External Build Files兩個組

在設計中cpp組用於存放專案的所有原生原始檔、標頭和預構建庫。對於當前專案,Android Studio只建立了一個名為native-lib.cpp的C++原始檔(位於src/main/cpp/目錄)其中只有一個簡單的C++函式stringFromJNI(),該函式返回字串“Hello from C++”。

External Build Files組用於存放CMake或ndk-build的構建指令碼。與Gradle需要build.gradle檔案來指示如何構建應用一樣,CMake和ndk-build依照一個構建指令碼來構建原生庫。對於當前專案,Android Studio建立了一個CMake構建指令碼CMakeLists.txt(位於模組的根目錄),用於指示編譯構建native-lib.cpp。

點選檢視“native-lib.cpp”內容如下,只有一個返回“Hello from C++”的函式

檢視生成的activity_main.xml,如容如下,和Android Studio正常預設生成的專案一樣,只有一個顯示“Hello World!”的文字框

檢視MainActivity.java內容如下,首選使用了System.loadLibrary()載入了本地庫,然後在onCreate()中將activity_main.xml中的文框的內容修改為原生函式stringFromJNI()返回的字串(Hello from C++)

 

我們直接在模擬器上執行app,如果介面文字框顯示的不是“Hello World!”而是“Hello from C++”那說明程式成功呼叫原生函式。

選單欄----Run----Run ‘app’選擇虛擬機器執行

圖中的”Nexus 5X API 28”是我之前建立的虛擬機器,沒有虛擬機器點選左下方的“Create New Virtual Device”建立即可。

可以看到介面如下,確實顯示的是“Hello from C++”,也就是說經過如此配置之後程式確實可以成功呼叫C++函式

 

1.4 建立新的原生原始檔【可選】

如果是簡單使用,那直接在上邊的native-lib.cpp後邊追加函式即可(不過要注意前邊的extern "C" JNIEXPORT jstring JNICALL相當於jstring,用於指明函式的返回值型別,自己在新增新函式時不要忘了需要指明返回值型別這回事,以致函式名位置一直報“Cannot resolve type”錯誤),在實際使用中經常需要建立多個檔案。下邊介紹如何建立新的原生原始檔。

1.4.1 建立新的原生原始檔

切換到“Project”檢視,定位到app--src-main--cpp,在其上右鍵New--C/C++ Source File

 

這裡我建立一個native-test.cpp

然後將native-lib.cpp中的函式複製過來,修改一下函式名和返回的字串

1.4.2 修改CMake構建指令碼

構建指令碼只能有一個,而且名字必須為CMakeLists.txt,我們在Project檢視app根目錄下找到CMakeLists.txt。

模仿書寫add_library()指出要生成的lib名及對應的原始檔

接下來修改MainActivity.java將預設生成的呼叫stringFromJNI()改為呼叫我們修改過的stringFromJNITest()

 

程式成功安裝執行,顯示字串也確實為"native-test:Hello from C++",證明成功呼叫

 

二、向已有專案新增新增C/C++程式碼

首先要明確,“為已有專案新增新增C/C++程式碼”其實質就要將“建立支援C/C++原生程式碼的新專案”中IDE自動為做好的步驟手動去實現。

C/C++原生程式碼支援在Android Studio中就是以下四步:第一步,安裝CMake/LLDB/NDK。第二步,在專案中建立原生原始檔。第三步,建立和編寫CMake構建指令碼CMakeLists.txt。第四步,向Gradle註冊構建請求。

手動實現時照葫蘆畫標即可。

 

2.1 安裝CMake/LLDB/NDK

與前邊1.1節一樣,不再贅述。

 

2.2 在專案中建立原生原始檔

寫入一個測試函式(這個函式就是“建立支援C/C++原生程式碼的新專案”時預設生成的函式,借過來用即可。不過千萬要注意函式名前的包名要改成自己當前的包名,不然在java中呼叫就報找不到函數了)

複製程式碼

#include <jni.h>
#include <string>

extern "C" JNIEXPORT jstring

JNICALL
Java_com_example_ls_test1_Main1Activity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

複製程式碼

 

 

2.3 建立和編寫CMake構建指令碼CMakeLists.txt

寫入以下內容(這裡“建立支援C/C++原生程式碼的新專案”時自動生成的內容,find_library和target_link_libraries還不很清楚什麼用但全複製進去準沒錯)

複製程式碼

cmake_minimum_required(VERSION 3.4.1)

add_library( # Sets the name of the library.
             native-lib

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             src/main/cpp/native-lib.cpp )

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 )

target_link_libraries( # Specifies the target library.
                       native-lib

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

複製程式碼

 

2.4 向Gradle註冊構建請求

開啟build.gradle向android/defaultConfig節區追加以下內容:

externalNativeBuild {
    cmake {
        cppFlags ""
    }
}

向android節區追加以下內容:

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

 

2.5 確認程式可以成功呼叫C++函式

這個和1.3一樣然證即可,我自己測試結果和1.3一樣是可以成功呼叫的。