AndroidStudio3.0 NDK開發- 如何在已有項目中進行NDK開發

源頭

因爲androidstudio 不斷地在完善ndk的開發,因此市面上好多文章已通過時了。 本文將從兩種方法來說解如何在androidstudio3.0 上進行ndk的配置。 本文章會學到以下操做:html

1.從建立項目進行ndk開發 2.在原有項目的基礎上進行ndk開發。 3.爲何生成的jni文件 沒法關聯 4.爲何c++代碼沒有自動提示java

##準備工做 下載一些ndk須要的工具 android

這裏寫圖片描述

從建立項目進行ndk開發

  • 在嚮導的 Configure your new project 部分,選中 Include C++ Support 複選框。
  • 點擊 Next。
  • 正常填寫全部其餘字段並完成嚮導接下來的幾個部分。
  • 在嚮導的 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。

上面的而操做都很簡單。獲得以下界面 c++

這裏寫圖片描述

  • 在 cpp 組中,您能夠找到屬於項目的全部原生源文件、標頭和預構建庫。對於新項目,Android Studio 會建立一個示例 C++ 源文件 native-lib.cpp,並將其置於應用模塊的 src/main/cpp/ 目錄中。本示例代碼提供了一個簡單的 C++ 函數 stringFromJNI(),此函數能夠返回字符串「Hello from C++」。bash

  • 在 External Build Files 組中,您能夠找到 CMake 或 ndk-build 的構建腳本。與 build.gradle 文件指示 Gradle 如何構建應用同樣,CMake 和 ndk-build 須要一個構建腳原本瞭解如何構建您的原生庫。對於新項目,Android Studio 會建立一個 CMake 構建腳本 CMakeLists.txt,並將其置於模塊的根目錄中。app

下面看一下 CMakeLists.txt 文件ide

# 有關使用CMake在Android Studio的更多信息,請閱讀文檔:https://d.android.com/studio/projects/add-native-code.html

# 設置CMake的最低版本構建本機所需庫
cmake_minimum_required(VERSION 3.4.1)

# 建立並命名庫,將其設置爲靜態的
# 或共享,並提供其源代碼的相對路徑。
# 你能夠定義多個library庫,並使用CMake來構建。
# Gradle會自動將包共享庫關聯到你的apk程序。

add_library( # 設置庫的名稱
             native-lib
             # 將庫設置爲共享庫。
             SHARED
             # 爲源文件提供一個相對路徑。
             src/main/cpp/native-lib.cpp )
# 搜索指定預先構建的庫和存儲路徑變量。由於CMake包括系統庫搜索路徑中默認狀況下,只須要指定想添加公共NDK庫的名稱,在CMake驗證庫以前存在完成構建
find_library( # 設置path變量的名稱
              log-lib
              # 在CMake定位前指定的NDK庫名稱
              log )
# 指定庫CMake應該連接到目標庫中,能夠連接多個庫,好比定義庫,構建腳本,預先構建的第三方庫或者系統庫
target_link_libraries( # 指定目標庫
                       native-lib
                       # 目標庫到日誌庫的連接 包含在NDK
                       ${log-lib} )
                       
複製代碼

##在原有項目的基礎上進行ndk開發函數

如今重點來了。大多數狀況加咱們建立項目並無引進 c++庫。那麼咱們要如何進行ndk開發呢。工具

爲了舉個例子咱們先建立一個 不引進c++庫的demo gradle

這裏寫圖片描述

咱們這裏沒有選中 c++的庫。而後一路next

就是一個 你最熟悉的樣子。沒有那些ndk相關的文件。

這裏寫圖片描述

  • 在main文件夾下右鍵新建一個叫作cpp的文件夾

  • 在MainActivity 中寫上 native的代碼

public class MainActivity extends AppCompatActivity {

    static {//導入libhello.so 文件。 這裏面只寫hello就能夠
        System.loadLibrary("hello");
    }

    public native String sayHello();


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        System.out.println(sayHello());
    }
}
複製代碼

如今寫完代碼 樣子是這樣的

這裏寫圖片描述
咱們發現sayHello是紅色的。不用管它

  • 生成.h文件
在命令行中執行以下代碼

 cd app/src/main/java/

javah sven.com.myapplication.MainActivity

複製代碼

生成了一個javah sven.com.myapplication.MainActivity.h 文件 而後吧這個文件複製到cpp 文件夾下

這裏寫圖片描述

  • 編寫 c++ 實現方法

建立.cpp 文件並進行代碼編寫 編寫以下代碼

這裏寫圖片描述
咱們看到 如今代碼提示找不到 文件。先到這一步不用管它

#include "Hello.h"
#include "sven_com_myapplication_MainActivity.h"

JNIEXPORT jstring JNICALL Java_sven_com_myapplication_MainActivity_sayHello
  (JNIEnv *, jobject){

  }
複製代碼
  • 建立一個 CMakeLists.txt 文件
    這裏寫圖片描述

這裏寫圖片描述

名字必須是 CMakeLists.tx 而後把下面這些代碼複製進去

cmake_minimum_required(VERSION 3.4.1)

 
add_library( # Specifies the name of the library.
# 這裏是你so的名字。剛纔在 MainActivity裏面要引用的 
             hello  

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
              #這裏是剛纔 建立的c++ 代碼的名字
             src/main/cpp/Hello.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.
# 這裏是你so的名字。剛纔在 MainActivity裏面要引用的 同樣。
                       hello

                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib} )
複製代碼
  • 引用 CMakeLists.txt 文件 直接在gradle中加上以下代碼
    這裏寫圖片描述
apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "sven.com.myapplication"
        minSdkVersion 14
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        ndk {
            abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a',
                    'arm64-v8a'
        }

        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
        externalNativeBuild {
            cmake {
                path "CMakeLists.txt"
            }
        }

    }

    dependencies {
        implementation fileTree(dir: 'libs', include: ['*.jar'])
        implementation 'com.android.support:appcompat-v7:26.1.0'
        implementation 'com.android.support.constraint:constraint-layout:1.0.2'
        testImplementation 'junit:junit:4.12'
        androidTestImplementation 'com.android.support.test:runner:1.0.1'
        androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
    }
複製代碼
  • 而後編譯一下。
    這裏寫圖片描述

這裏寫圖片描述

好了。咱們發現 sayHello 不報紅 了。cpp 文件中的代碼也能夠 引用了。

  • 生成so文件 make 一下項目
    這裏寫圖片描述

而後就生成了so文件

這裏寫圖片描述

最後

到這一步咱們就大功告成了。 能夠在原來的項目中進行ndk的開發了

相關文章
相關標籤/搜索