Android Studio 配置 NDK(一)
什麼是ndk, 簡單的講就是ndk可以讓你調用到c/c++方法來實現一些比較安全的功能,例如你完全可以將Android程序的數據 通過c/c++原來編寫存儲, 然後通過jni方式調用方法,而且在實現的時候, 也可以各種加密,讓後程序的數據更加安全。
最近想給項目應用增量更新,所以就折騰了一下ndk。
和以往的ndk開發方式不太一樣。
1.現在查到的資料大部分套路都是需要先通過javah文件方式生成.h文件, 然後寫對應的實現文件.c /. cpp,最終配置文件Android.mk, Application.mk,放在jni目錄下, 執行ndk-build命令,最終生成可用的.so庫
2.使用官方提供的gradle-experimental插件(gradle的版本和插件版本要對應),照着官方文檔在gradle中一頓配置後, 編寫native 方法,alter+enter鍵,最終還是未出來。
最終發現, 其實現在的android studio都是很智能,配置好模塊,make project的時候自動幫你編譯生成.so庫文件, 基本上不用配置什麼,最終還是能很容易的就編出hello world。這裏只是簡單的講一下ndk建立項目的一些初步問題, 高手請繞道。
1.新建立一個項目:
2.配置gradle
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "com.caldremch.myapplication"
minSdkVersion 15
targetSdkVersion 25
versionCode 1
versionName "1.0"
ndk{
moduleName = "cade"
//abiFilters "x86","armeabi-v7a" //這裏填寫兩個abi cpu架構,如果什麼都不寫,則默認支持所有平臺
}
}
3.建立一個類 ,包含native方法,此時會有看到方法是紅色的, 這很正常的
public class JNITest {
static {
System.loadLibrary("cade"); //這裏的cade跟gradle配置的modulename一致
}
public native String getAA(); //native方法
}
4.切刀java目錄 ,輸入命令.javah -d ../jni 包名.類名(例如com.cade.utils.JNITest)
,生成.h文件, 編寫對應的.c文件
hello.c文件爲:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <string.h>
#include "hello.h" //這裏注意, 如果剛纔沒有改文件名,那麼這裏就不是hello.h了
jstring Java_com_caldremch_myapplication_JNITest_getAA
(JNIEnv * env, jobject clazz)
{
return (*env)->NewStringUTF(env, "測試成功沒有");
}
準備工作已經差不多了, 接下里還要在gradle.properties文件中加上一句:
android.useDeprecatedNdk=true //不加有可能導致編譯不成功
執行編譯:菜單欄 build—》make project(��圖標)
在MainActivity中引測試:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = (TextView) findViewById(R.id.text);
textView.setText(new JNITest().getAA());
}
接下來我們看看到底.so庫在哪裏生成了?
看到結果了吧。
這裏說幾點:
1.配置不讓gradle自動編譯,自己編譯,那麼在build.gradleandroid節點下設置
// sourceSets.main{
// jni.srcDirs = []//設置禁止gradle生成Android.mk
// jniLibs.srcDirs = ['src/main/jniLibs']//設置目標的so存放路徑
// }
2.如果一個項目中,有多個引用的.so庫, 請注意一點, 一定讓它們支持的cpu abi數量和類型 一樣。不然會報錯 java.lang.UnsatisfiedLinkError
例如在一同一個項目中有ndk模塊
ndk {
moduleName = 'module1'
abiFilters "x86","armeabi-v7a"
在另一個依賴項目:
ndk {
moduleName = 'module2'
abiFilters "x86","armeabi-v7a"
如果它們 abiFilters不一樣,數量或者類型有別, 那麼將導致錯誤。