Android初涉NDK,從零打造你的第一個demo

 最近打算重構項目中的部分代碼,將部分耗時或者敏感的代碼放到native中實現。說來慚愧,本人今年3月份纔開始接觸android開發,雖然一早就知道android中可使用c/c++代碼,但一直沒有嘗試。因而趁着此次機會研究一下android中的ndk 開發,花了一個下午加一個上午,經歷了種種悲劇後終於跑通了第一個demo。在整個過程當中參考了無數文章,也走了不少彎路,特此寫下本文章,但願幫助剛剛接觸JNI的童鞋們更快的上手。

    上面說的貌似是廢話,如今開始進入正題。個人開發環境是windows+eclipse,所以在開始真正寫代碼前,還須要在windows上搭建相關環境才能編譯.so文件。這裏我推薦看下 http://www.cnblogs.com/jdksummer/articles/2166057.html 這篇配置文章寫的很詳細。 html

    假設你如今已經搭建好了開發環境,那麼開始吧!(聽着音樂,開始咱們的學習吧!!)
java

    1.打開eclipse新建一個android的工程,就叫"MyFirstJNI"吧。創建後添加一個class文件做爲jni的接口,我是這樣添加的
android

在該類中添加以下代碼:都是一些很簡單的函數^^ c++

1 packagecom.example.myjni;
2
3 publicclassJNI {
4    publicnativevoidwrite();
5    publicnativeString sayHello();
6    publicnativeintplus(inta,intb);
7 }

這個就是native code在java中的接口了。添加完成後,build project。第一步的準備工做就此完成,很容易吧。 windows

    2.打開cmd並定位到剛剛新建的"MyFirstJNI"工程目錄下的bin/classes目錄,執行」javah -classpath .  -jni  com.example.myjni.JNI「,沒有意外的話,bin/classes目錄下應該會產生一個com_example_myjni_JNI.h文件。這個就是native code須要實現的函數了。 eclipse


    3.如今咱們把剛剛獲得的.h文件拷貝出,爲它新建一個工程,我是手工創建的。創建D:\MyfirstJNISO目錄,並創建子目錄jni(必須叫這個,不然後面會不能編譯哦),並將.h文件拷貝到該目錄下,並新建一個com_example_myjni_JNI.c文件實現相關函數,代碼以下: 函數

01 #include <string.h>
02 #include "com_example_myjni_JNI.h"
03
04
05
06 JNIEXPORTvoidJNICALL Java_com_example_myjni_JNI_write
07  (JNIEnv *env, jobject thiz)
08  {
09    
10  }
11
12 /*
13 * Class:     com_example_myjni_JNI
14 * Method:    sayHello
15 * Signature: ()Ljava/lang/String;
16 */
17 JNIEXPORT jstring JNICALL Java_com_example_myjni_JNI_sayHello
18  (JNIEnv *env, jobject thiz)
19 {
20    return(*env)->NewStringUTF(env,"Hello from JNI !");
21 }
22
23 /*
24 * Class:     com_example_myjni_JNI
25 * Method:    plus
26 * Signature: (II)I
27 */
28 JNIEXPORT jint JNICALL Java_com_example_myjni_JNI_plus
29  (JNIEnv *env, jobject thiz, jint a, jint b)
30  {
31    returna+b;
32  }

接着還須要同一個目錄下添加一個Android.mk文件,編譯時候使用,具體內容以下: 學習

LOCAL_PATH := $(call my-dir) 測試

include $(CLEAR_VARS) ui

LOCAL_MODULE    := first_jni                                 (最終so文件名是libfirst_jni.so

LOCAL_SRC_FILES := com_example_myjni_JNI.c       (代碼)

include $(BUILD_SHARED_LIBRARY)

是否是很麻煩,不過咱們已經離成功愈來愈近了。

    3.如今整理一下,咱們到目前爲止的工做,新建了一個android工程以及一個C的工程(暫且叫工程吧),如今開始最重要的一步,編譯c代碼生成.so文件讓android工程中的調用。你如今應該已經配置好了cygwin了吧,打開吧,定位到C工程目錄,好比D:\myfirstJNISO的話就執行」cd /cygdrive/D/myfirstJNISO「,而後執行」$NDK/ndk-build

「(其中$NDK和你配置的cygwin有關)。


這樣編譯的工做就完成了,若是你前面沒有犯任何錯的話。趕忙打開C工程目錄吧應該是這樣的吧


黃色標記的目錄就是咱們須要的東西哦,裏面是一個」armeabi「文件夾,裏面是編譯獲得的.so文件。

     final.將上面的armeabi文件夾整個拷貝到咱們一開始創建的MyfirstJNI工程的libs目錄下,全部工做都已就緒,你的工程應該是這樣的:

(ps:請忽略android-support-v4.jar這個和本次的內容不要緊)

如今就來編寫java代碼調用吧,在MainActivity中添加必須的代碼:

1 static{
2    System.loadLibrary("first_jni");
3 }

這個是讓系統加載so庫,注意編譯生成的庫的名字是帶前綴lib的,代碼中請忽略不然會找不到相應的so文件。

調用就很簡單了:

1 jni =newJNI();
2
3 jni.sayHello();
4
5 jni.plus(1,2);

最後添加一些簡單的button測試一下吧,我作的比較簡陋了:


至此,咱們的第一個ndk的demo就跑起來了。

相關文章
相關標籤/搜索