前言
網(wǎng)上關于NDK開發(fā)環(huán)境配置的相關博客已經(jīng)很多,但是很少有關于NDK在AdnroidStduio 3.0以上的環(huán)境搭建相關的博客.所以特此記錄下.
首先是對NDK的介紹,先對NDK有個初步的印象:
NDK(Native Development kit)是一個工作集,為了能讓開發(fā)者可以更加直接的接觸Android硬件資源和方便地使用傳統(tǒng)的C/C++語言編寫代碼,NDK應運而生。在NDK公布以前沼侣,Android平臺的第三方應用程序的編寫只能依靠基于Java的Dalvik虛擬機進行開發(fā)综膀。有了NDK后,開發(fā)者就可以更加方便的用傳統(tǒng)的C/C++語言編寫程序葛躏,并在程序封裝文件(.apk)中直接嵌入
- NDK提供了一系列的工具澈段,幫助開發(fā)者快速開發(fā)C(或C++)的動態(tài)庫,并能自動將so和java應用一起打包成apk紫新。這些工具對開發(fā)者的幫助是巨大的均蜜。
- NDK集成了交叉編譯器,并提供了相應的mk文件隔離CPU芒率、平臺囤耳、ABI等差異,開發(fā)人員只需要簡單修改mk文件(指出“哪些文件需要編譯”偶芍、“編譯特性要求”等)充择,就可以創(chuàng)建出so。
- NDK可以自動地將so和Java應用一起打包匪蟀,極大地減輕了開發(fā)人員的打包工作椎麦。
下載工具
- NDK: NDK Downloads
- CMake:一個外部構建工具(AndroidStudio 3.0以上自帶)
- LLDB:用于調(diào)試本地代碼
這些工具都可以使用SDM Manager下載
當前博客所用的列子的環(huán)境如下
名稱 | 版本號 |
---|---|
AndroidStudio | 3.0 |
JDK | jdk1.8.0_101 |
NDk | 16.1.4479499 |
compileSdkVersion | 26 |
buildToolsVersion | 26.1.0 |
minSdkVersion | 21 |
targetSdkVersion | 26 |
創(chuàng)建一個NDK項目
new一個項目,并勾選include c++ support
AndroidStudio 3.0上創(chuàng)建NDK項目的時候,記得勾選include c++ support,這樣會很方便.接著一路next 最后點擊finish.
這樣一個NDK項目就已經(jīng)創(chuàng)建好了,目錄結構以及代碼如下
可以看出來AS3.0勾選了include c++ support會比正常的項目多出來cpp文件夾跟CmakeLists.txt文件.這些將是我們在AS3.0上學習NDK環(huán)境開發(fā)的重點
這樣一個NDK的項目就完全建好了,并且可以運行,我們來看下運行的效果
哈哈,是不是很方便?如果之前沒有勾選include c++ support 就會很麻煩,這個可以在以后的博客里說下舊的NDK項目怎么在3.0上運行,3.0已經(jīng)不同于2.0,現(xiàn)在先享受下AS給我們帶來的方便吧~
我們的項目里面Jni文件肯定不止一個,如果需要新的Jni文件的話,請按下面的步驟來
NDK自定義配置過程
創(chuàng)建一個Java文件
在這個類里面寫一個native方法
生成頭文件(*.h)
打開Terminal,給剛剛創(chuàng)建的類創(chuàng)建頭文件.先cd到app/src/main/java目錄下
cd app/src/main/java
然后使用javah命令
javah -d ../cpp com.vv.ndk.Hello
javah 執(zhí)行java命令生成頭文件(*.h)
-d 在當前目錄下創(chuàng)建一個文件夾,文件夾名字是cpp
com.vv.ndk.Hello 包名.類名指定要生成那個java類文件的頭文件
所以這個命令的目的是在cpp的上一層目錄下創(chuàng)建一個cpp文件夾,并對com.vv.ndk.Hello
生成一個頭文件,如下圖所示:
這個命令輸入完以后在app/src/main/cpp/文件夾下多了一個com_vv_ndk_Hello.h
文件,并且這個文件里面有一個未實現(xiàn)的方法Java_com_vv_ndk_Hello_sayHello
,這個方法就是Hello.java方法里面對應的sayHello()方法
創(chuàng)建c文件并實現(xiàn)頭文件里面的方法
Java_com_vv_ndk_Hello_sayHello
這個文件是一個抽象的方法,我們需要創(chuàng)建一個*.c文件去實現(xiàn)這個方法.
-
我們在cpp文件夾下創(chuàng)建一個C++ Source File,命名為Hello.cpp
引入
com_vv_ndk_Hello.h
頭文件,并實現(xiàn)頭文件里面的Java_com_vv_ndk_Hello_sayHello
方法
- 返回一個我們想要得到的值,代碼如下
#include "com_vv_ndk_Hello.h"
JNIEXPORT jstring JNICALL Java_com_vv_ndk_Hello_sayHello(JNIEnv *env, jclass jclass1){
return env->NewStringUTF("say Hello");
}
Java文件里面加入靜態(tài)方法塊
System.loadLibrary("hello")
是NDK的moduleName
配置grade
在app.gradle
文件的defaultConfig里面加上 ndk 的moduleName
defaultConfig {
...
ndk{
moduleName "hello"
}
}
在Activity里面調(diào)用Jni
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = (TextView) findViewById(R.id.sample_text);
tv.setText(Hello.sayHello());
}
}
運行以后發(fā)現(xiàn)崩潰,不要慌
崩潰是因為你還沒有配置最關鍵的CmakeLists.txt文件
配置CmakeLists.txt文件
add_library( # Sets the name of the library.
hello
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
src/main/jni/Hello.cpp
src/main/jni/Hi.cpp
)
target_link_libraries( hello ${log-lib} )
ok,運行
效果如下
這樣調(diào)用Hello.sayHello()方法就顯示出來了.
總結
以上是創(chuàng)建NDK項目的過程,現(xiàn)在我們來總結下創(chuàng)建的整個步驟.
- 創(chuàng)建一個Java文件
- 在這個類里面寫一個native方法
- 生成頭文件(*.h)
- 創(chuàng)建c文件并實現(xiàn)頭文件里面的方法
- Java文件里面加入靜態(tài)方法塊
- 配置grade
- 在Activity里面調(diào)用Jni
- 配置CmakeLists.txt文件
博客就到這里吧,下面將會講下CMakeLists的解析,看看這個文件到底是個啥.