因爲androidstudio 不斷地在完善ndk的開發,因此市面上好多文章已通過時了。 本文將從兩種方法來說解如何在androidstudio3.0 上進行ndk的配置。 本文章會學到以下操做:html
1.從建立項目進行ndk開發 2.在原有項目的基礎上進行ndk開發。 3.爲何生成的jni文件 沒法關聯 4.爲何c++代碼沒有自動提示java
##準備工做 下載一些ndk須要的工具 android
上面的而操做都很簡單。獲得以下界面 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());
}
}
複製代碼
如今寫完代碼 樣子是這樣的
在命令行中執行以下代碼
cd app/src/main/java/
javah sven.com.myapplication.MainActivity
複製代碼
生成了一個javah sven.com.myapplication.MainActivity.h 文件 而後吧這個文件複製到cpp 文件夾下
建立.cpp 文件並進行代碼編寫 編寫以下代碼
#include "Hello.h"
#include "sven_com_myapplication_MainActivity.h"
JNIEXPORT jstring JNICALL Java_sven_com_myapplication_MainActivity_sayHello
(JNIEnv *, jobject){
}
複製代碼
名字必須是 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} )
複製代碼
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文件
到這一步咱們就大功告成了。 能夠在原來的項目中進行ndk的開發了