Android Studio下NDK的使用
當我們在開發android程式的過程中,有時候需要應用程式對底層硬體的調用。android官方給我們提供NDK以便於我們在我們的程式中調用C,C++庫。Ndk是基於JAVA JNI技術所開發的一套應用於android編程的一系列工具集合,她可以協助我們快速開發C或者C++的動態庫並和應用一起打包產生APK。
關於JNI的原理,請參考 [ JAVA基礎之理解JNI原理]
NDK的下載與安裝前往前往http://developer.android.com/ndk/downloads/index.html。
或者國內諸多鏡像網站
下載完成後直接解壓後即可使用
NDK的在Android Studio中的使用
1、建立一個Android Studio工程
2、配置工程中NDK的路徑
file->project structure
點擊確定後,你的local.prZ喎?http://www.bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vcGVydGllc87EvP7PwsPmtuDBy9K70NBuZGu1xMK3vrY8L3A+DQo8cD48aW1nIGFsdD0="這裡寫圖片描述" src="http://www.bkjia.com/uploads/allimg/160412/0411155916-2.png" title="\" />
3、建立一個NDKTest類並編寫如下代碼
public class NDKTest { static { System.loadLibrary("ndk_test"); } public native static String hello();}
4、rebuild一下項目後,將工程求換到project目錄
bebug目錄下面已經產生了剛才編寫的NDKTest檔案的.class檔案
然後我們通過terminal進入到這個目錄下面
使用javah產生c.h標頭檔
javah -jni com.hehao.ndkdemo.ndk.NDKTest
執行完成後將產生com_hehao_ndkdemo_ndk_NDKTest.h的一個C檔案
接下來在main目錄下面。建立一個jni目錄
把我們之前用javah產生的.h標頭檔拷貝或者剪下到jni目錄中去
建立一個C檔案來實現頭標頭檔中聲明的函數(名字隨意)但是通常我們會使用java+包名+類名這樣的名字
並在檔案中添加如下代碼
#include "com_hehao_ndkdemo_ndk_NDKTest.h"/** Class: Java_com_hehao_ndkdemo_ndk_Test* Method: test* Signature: ()Ljava/lang/String;*/JNIEXPORT jstring JNICALL Java_com_hehao_ndkdemo_ndk_NDKTest_hello (JNIEnv *env, jobject obj){ return env->NewStringUTF("這裡是來自c的:hello world!");}
然後我們使用剛才的rebuild操作再重新構建一下項目 Build->Rebuild Project
PS:然後我發現項目報錯了
不知道為什麼,重啟一下AS後重新Rebuild一下,搞定
然後在啟動並執行時候又提示了這個錯誤
按照他說的我們去gradle.properties的末尾添加一行代碼
android.useDeprecatedNdk=true
再來 又報錯了
這個錯誤百度了很多資料,據說是NDK在windows下面的一個bug。我也沒有考證,引用別人的說法。
解決辦發是在jni目錄下建立一個空的c檔案
再來,終於運行成功了。然後我們在mainActivity中嘗試調用一下NDK類的代碼
package com.hehao.ndkdemo;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.widget.TextView;import com.hehao.ndkdemo.ndk.NDKTest;public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView textView = (TextView) findViewById(R.id.ndk_test); textView.setText(NDKTest.hello()); }}
然後發現出錯了
一定位,發現載入類的時候出問題了
這時,需要在App模組的gradle檔案中添加
ndk { moduleName "ndk_test" //產生的so名字 abiFilters "armeabi", "armeabi-v7a", "x86" //輸出指定三種abi體繫結構下的so庫,目前可有可無}
產生的.so檔案要和我們在之前建立的Java檔案中引入的保持一致
成功