NDK開發(一) :NDK入門指南

轉載請以連接形式標明出處: 本文出自:103style的博客html

本文操做以 Android Studio 3.4.2 版本爲例java

NDK開發文章彙總android


目錄

  • 環境配置
  • 建立支持 C/C++ 的新項目
  • 向現有項目添加 C/C++ 代碼
  • 參考文章

環境配置

  • 下載安裝 Android Studio
  • 配置 NDK 環境
    • 啓動 Android Studio.
    • 以下圖:在界面的 Configure 中 打開 Settings 界面。
      進入Android Studio 設置界面
    • 以下圖: 在 左上角 輸入框輸入sdk → 點擊 Android SDK → 點擊 SDK Tools → 而後勾選上 LLDBCMakeNDK → 而後點擊 OK → 點擊彈出框中的 OK.
      安裝NDK環境步驟圖
    • 下載安裝完成以後,重啓 Android Studio.

建立支持 C/C++ 的新項目

  • Android Studio 的界面,點擊 Start a new Android Studio project
  • 以下圖,在彈出界面選擇 Native C++ ,而後點擊 Next
    選擇Native C++
  • 在新的界面直接點擊 Next, 或者修改Name, Package name , Save location 中的值;
  • 在新的界面點擊 Finish.

Android Studio將會爲咱們生成一個模板工程,咱們能夠直接運行,啓動以後界面上會顯示 Hello from C++git


支持 C/C++ 的項目文件介紹

Android Studio 左側打開 Project 窗格並選擇 Android 視圖,以下圖: github

支持C/C++ 的項目結構圖

咱們只要關心上圖紅框標記出來的如下這些文件就好:bash

  • MainActivity :應用視圖界面,加載了一個名爲native-lib的庫,定義了一個native的方法stringFromJNI,而後將stringFromJNI返回的值設置到TextView上。
    public class MainActivity extends AppCompatActivity {
        static {
            System.loadLibrary("native-lib");
        }
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            ...
            tv.setText(stringFromJNI());
        }
        public native String stringFromJNI();
    }
    複製代碼
  • CMakeLists.txt :CMake 構建腳本。
    # 設置CMake的最低版本
    cmake_minimum_required(VERSION 3.4.1)
    # 添加源文件或者庫
    add_library(
            native-lib # 庫的名字
            SHARED # 庫的類型 
            native-lib.cpp) # 庫的源文件
    # 引用NDK中的庫log,命名爲log-lib
    find_library(
            log-lib # 庫路徑對應的變量名
            log) # NDK中的庫名
    # 關聯庫,確保 native-lib 中 能使用 log 庫
    target_link_libraries(
            native-lib 
            ${log-lib})
    複製代碼
  • native-lib.cpp : 示例 C++ 源文件,位於src/main/cpp/目錄。
    #include <jni.h>
    #include <string>
    
    extern "C" JNIEXPORT jstring JNICALL
    //MainActivity 中 stringFromJNI方法 對應的 c 方法名字
    Java_com_lxk_myapplication_MainActivity_stringFromJNI(
            JNIEnv *env,
            jobject ) {
        std::string hello = "Hello from C++";
        return env->NewStringUTF(hello.c_str());
    }
    複製代碼
  • build.gradle :構建文件
    android {
        ...
        defaultConfig {
            ...
            externalNativeBuild {
                cmake {
                    cppFlags ""
                }
            }
        }
        externalNativeBuild {
            cmake {
                path "src/main/cpp/CMakeLists.txt" //構建腳本的路徑
                version "3.10.2"//CMake的版本
            }
        }
    }
    複製代碼

若是剛剛運行過項目的話,點擊左側Project 窗格並選擇 Project 視圖,會在 app/build/intermediates/cmake/debug/armeabi-v7a/下生成一個 libnative-lib.so文件。app

CMake 使用 lib庫名稱.so 的規範來爲庫文件命名,庫名稱即爲咱們定義的 native-lib。不過咱們在Java代碼中加載時,仍是使用咱們定義的庫名稱 native-libide

static {
    System.loadLibrary("native-lib");
}
複製代碼

向現有項目添加 C/C++ 代碼

向現有 Android Studio 項目添加或導入原生代碼,則須要按如下基本流程操做:函數

  • 建立新的原生源文件,並將其添加到 Android Studio 項目中,若是您已經擁有原生代碼或想要導入預編譯原生庫,則可跳過此步驟。
  • 建立 CMake 編譯腳本,告知 CMake 如何將原生源文件編譯入庫。若是導入和關聯預編譯庫或平臺庫,您也須要此編譯腳本。若是現有的原生庫已有 CMakeLists.txt 編譯腳本,或使用 ndk-build 幷包含 Android.mk編譯腳本,則可跳過此步驟。
  • 提供一個指向 CMake 或 ndk-build 腳本文件的路徑,將 Gradle 關聯到原生庫。Gradle 使用編譯腳本將源代碼導入您的 Android Studio 項目並將原生庫(.so文件)打包到 APK 中。
從新建立一個 Basic Activity的工程。

Basic Activity

建立新的原生源文件
  • 從左側打開 Project 菜單並從下拉菜單中選擇 Project 視圖。
  • 右鍵點擊選中 app/src/ 下的 main 目錄,而後選擇 New > Directory,爲目錄輸入一個名稱(例如 cpp)並點擊 OK
  • 右鍵點擊您剛剛建立的目錄,而後選擇 New > C/C++ Source File,輸入一個名稱,例如 hello-ndk,若是想建立一個標頭文件,請勾選 Create an associated header 複選框,點擊 OK
建立 CMake 構建腳本

若是您的原生源文件尚未 CMake 構建腳本,則您須要自行建立一個幷包含適當的 CMake 命令。工具

必須將其命名爲 CMakeLists.txt

  • 右鍵點擊選中 app ,而後選擇 New > File,輸入CMakeLists.txt 做爲文件名並點擊 OK
  • 添加命令到 CMakeLists.txt
    cmake_minimum_required(VERSION 3.4.1)
    
    add_library( hello-ndk
                 SHARED
                 src/main/cpp/hello-ndk.cpp)
    複製代碼
  • 使用 add_library() 向您的 CMake 構建腳本添加源文件或庫時,Android Studio 還會在您同步項目後在 Project 視圖下顯示關聯的標頭文件。不過,爲了確保 CMake 能夠在編譯時定位您的標頭文件,您須要將 include_directories()命令添加到 CMake 構建腳本中並指定標頭的路徑:
    add_library(...)
    
    include_directories(src/main/cpp/include/)
    複製代碼
  • 添加 NDK APIAndroid NDK 提供了一套實用的原生 API 和庫。將 find_library() 命令添加到您的 CMake 構建腳本中以定位 NDK 庫。以 Android 特定的日誌支持庫 爲例,爲了確保您的原生庫能夠在 log 庫中調用函數,您須要使用 CMake 構建腳本中的 target_link_libraries()命令關聯庫:
    add_library(...)
    
    find_library( log-lib # 庫路徑的變量名
                  log ) # 對應的庫名
    
    #將預構建庫關聯到您本身的原生庫 
    target_link_libraries( hello-ndk
                           ${log-lib} )
    複製代碼
將 Gradle 關聯到您的原生庫

要將 Gradle 關聯到您的原生庫,您須要提供一個指向 CMakendk-build 腳本文件的路徑。在您構建應用時,Gradle 會以依賴項的形式運行 CMakendk-build,並將共享的庫打包到您的 APK 中。

  • 點擊Android Studio 左側菜單 Project 並選擇 Android 視圖。 點擊 彈出菜單的第二個選項 Link C++ Project with Gradle,如圖1,點擊文件夾,點擊 Android Studio圖標的按鈕能夠定位到項目根目錄,而後如圖2 配置 CMakeLists.txt 的路徑,點擊 OK
    點擊能夠定位到項目根目錄

  • 而後 app目錄下的build.gradle文件會自動添加如下代碼。
    externalNativeBuild {
        cmake {
            path file('CMakeLists.txt')
        }
    }
    複製代碼
配置Javah命令工具<可選>

以下圖,按 Ctrl + Alt + s 進入 Setting 界面,點擊 Tools → External Tools → + 配置添加外部工具。參數以下:

Name :JavaH
Program:$JDKPath$/bin/javah
Parameters: -encoding UTF-8 -d ../cpp -jni $FileClass$
Working directory: $SourcepathEntry$\..\java
複製代碼

配置Javah命令工具

編輯 MainActivity

MainActivity 添加以下代碼:

public class MainActivity extends AppCompatActivity {
    static {
        System.loadLibrary("hello-ndk");
    }
    public native String helloNDK();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        //添加下面兩行代碼
        TextView show = findViewById(R.id.tv_show);
        show.setText(helloNDK());

        ....
    }
    ...
}
複製代碼
修改 content_main.xml

修改 content_main.xml,給TextView添加 android:id="@+id/tv_show"

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    ...>

    <TextView
        android:id="@+id/tv_show"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        .../>
</android.support.constraint.ConstraintLayout>
複製代碼
生成 .h 頭文件 <可選>

以下圖,右鍵點擊MainActivity,選擇彈出框中的 External ToolsJavaH 。就會在cpp目錄下生成 com_example_myapplication_MainActivity.h文件,你的文件名可能不同。

生成 .h 頭文件

編輯hello-ndk.cpp

修改hello-ndk.cpp爲如下代碼:

#include <jni.h>
//確認此處名字是否可你生成的頭文件的名字同樣
#include "com_example_myapplication_MainActivity.h" 

//函數名要和頭文件中的名字一致
JNIEXPORT jstring JNICALL Java_com_example_myapplication_MainActivity_helloNDK  
  (JNIEnv * env, jobject){
    return env ->NewStringUTF("Hello NDK");
}
複製代碼
運行程序

點擊頂部菜單欄 Build 中的 Rebuild Project,完了以後按 Shirt + F10 運行程序,而後界面上就會顯示 Hello NDK 的字樣。


參考文章


Demo地址

若是以爲不錯的話,請幫忙點個讚唄。

以上


掃描下面的二維碼,關注個人公衆號 Android1024, 點關注,不迷路。

Android1024
相關文章
相關標籤/搜索