Netbeans玩轉ndk

1.       引言

這兩天研究了下ndk開發,由於公司android播放器,後續開發須要調用底層so庫,網上查了不少資料全都是eclipse,可是我用的是netbeans只好自行研究,ndk很簡單,baidu一下資料不少,若是你是一個有經驗的程序員,分分鐘就能夠搞定,編譯出一個so來。 html

主要問題就在於如何將soapk打包到一塊兒。 java

Eclipse是經過ADT插件自動完成的,也能夠本身編寫ant腳本,經過ant打包,這就不在本文範圍內了。 linux

1.1. 目的

讓習慣netbeans的程序員,排斥eclipse的程序員可以順利的完成他們的android開發,也讓像學習ndk開發的人可以快速入門 android

 

1.2. 可能閱讀者

VC基礎,想搞android開發的開發的技術人員 c++

使用netbeansandroid開發人員(通常也都是VC轉過來的,由於VS IDENetbeansIDE風格比較類似) 程序員

2.       開發工具體系

Netbeans 算法

本教程使用的是6.8,但不限於6.8版本(自行下載安裝) windows

用於開發android app api

Ndk開發環境: 安全

用於開發供app調用的so本地庫

Windows開發環境包含如下2個軟件包

n  Ndk開發包android-ndk-r8d-windows.zip

下載連接http://dl.google.com/android/ndk/android-ndk-r8d-windows.zip

若是打不開,能夠進入下載頁面

http://developer.android.com/tools/sdk/ndk/index.html#download下載

n  Linux模擬環境cygwin

http://www.cygwin.com/

2.1. 搭建安裝環境

第2步.         下載Ndk開發包

第3步.         解壓到任意位置(本例:F:\ndk)目錄結構如圖


第4步.         Ndk安裝就完成了,該安裝cygwin

第5步.         下載cygwin.zip,這個是網絡安裝器,下載好有900M就不打包在本教程中了

第6步.         安裝cygwin,選擇第一個,從網上下載安裝,如圖

                    

第7步.         設置安裝目錄,如圖


第8步.         設置下載到安裝文件保存位置,如圖


安裝完成後,本地就有下載好的包,之後在別的機器從新安裝時就能夠選擇第3項,從本地安裝,選者這裏設置的目錄

第9步.         而後一直默認懸想,一直下一步,到如圖步驟,選擇一個下載站點,通常選擇163速度還能夠


第10步.     選擇要安裝的模塊,只要安裝Devel就夠了,如圖


第11步.     等待安裝完成吧,大小是900M

第12步.     驗證cygwin安裝

n  運行安裝目錄下的「Cygwin.bat」,第一次運行時,它會自動建立用戶信息,用戶信息存放在「.\Cygwin\home」中。

n  在運行「Cygwin.bat」打開的命令行窗口輸入:「cygcheck -c cygwin」命令,會打印出當前Cygwin的版本和運行狀態,若是statusok的話,則cygwin運行正常。

n  分別輸入:「make –v」和,「gcc –v」命令若是檢測成功,會有makegcc相關版本信息打印出來。

如圖


第13步.     Ndk開發環境搭建完成

第14步.     在系統環境變量中配置ndk目錄(可選的操做,主要是爲了方便),如圖

cygwinlinux模擬環境,訪問windows磁盤的方式是/cygdrive/盤符


2.2. 嘗試編譯一個so

直接使用附帶jni例子

進入目錄F:\ndk\\jni目錄


編譯hello-jni


編譯後就會生成so文件了,這個文件就能夠供android應用程序調用


 

2.3. netbeans建立的android項目中使用剛纔編譯出來的so本地庫

第1步.         建立android項目calljni

第2步.         添加HelloJni類,代碼以下

package com.example.hellojni;

 

public class HelloJni

{

    /* A native method that is implemented by the

     * 'hello-jni' native library, which is packaged

     * with this application.

     */

    public native String  stringFromJNI();

 

    /* this is used to load the 'hello-jni' library on application

     * startup. The library has already been unpacked into

     * /data/data/com.example.hellojni/lib/libhello-jni.so at

     * installation time by the package manager.

     */

    static {

        System.loadLibrary("hello-jni");

    }

}

第3步.         MainActivity類中添加調用代碼

    public void onCreate(Bundle icicle) {

        super.onCreate(icicle);

        // ToDo add your GUI initialization code here       

        lib.stringFromJNI();

        TextView  tv = new TextView(this);

        tv.setText( lib.stringFromJNI() );

        setContentView(tv);

}

第4步.         so文件添加到工程目錄\lib\armeabi下,添加後so位置如圖


第5步.         Netbeans區別於eclipes的關鍵步驟

1)        編輯F:\ndk\calljni\nbproject\build-impl.xml文件

2)        找到name="-sign"target 也就是執行apkbuildtarget

3)        在全部指令以前,加入如下指令,執行aaptso打包進apk_

<exec executable="${aapt}" failonerror="true">

     <arg value="a"/>

     <arg value="${dist.apk}_"/>

     <arg value="lib/armeabi/libhello-jni.so"/>

</exec>

 

若是有多個so須要打包進去,就多添加幾條以上指令

 

這一步就是幫助netbeans的用戶解決,如何把so文件打包進apk中這個難題。

你們都知道Apk就是一個zip格式的包,可是你不能直接將so文件打包進編譯出來的apk中,由於apk是要簽名纔有效的,裏面有簽名文件如圖中,打開查看,是經過hash算法計算出來的,因此必須在簽名以前,把so文件打包進去一塊兒簽名,因此必須本身修改項目的編譯腳本文件(其實就是ant編譯腳本)。

 


 

 

第6步.         編譯項目生成calljni.apk,在模擬器運行結果如圖


2.4. ndk開發體系相關

1.  什麼是NDK

NDK 提供了一系列的工具,幫助開發者快速開發C/C++的動態庫(so文件),經過mk 文件隔離CPU、平臺、ABI 等差別,開發人員只須要簡單修改mk 文件(指出哪些文件須要編譯編譯特性要求等),就能夠建立出so,使你能夠在你的Android程序當中用Java語言(JNI)調用這些c/c++代碼.

 

Google明確聲明該API是穩定的,在後續全部版本中都穩定支持當前發佈的API。從該版本的NDK中看出,這些API支持的功能很是有限,包含有:C標準庫(libc)、標準數學庫(libm)、壓縮庫(libz)、Log庫(liblog

2.  so文件必須使用ndk編譯?

不是,能夠直接在linux下編譯so,可是你得確保你所使用的api是操做系統所支持,就是上面google聲明中說的ndk支持的庫,若是是特定平臺支持的api,那可能就只有部分手機能夠正常運行

3.  mk文件如何編寫

附件提供mk模板一分,可參考編寫

4.  網上說的使用javah生成c/c++ .h文件,是否必須

不是,徹底不須要,給出java生成.h文件的指令,和先決條件

javah -classpath ./build/classes -d jni org.me.calljni.MainActivity

首先必須編譯java類,無論你用任何方式,編譯出來就行,生成類.class文件,

而後使用以上指令生成頭文件-classpath後面的目錄就是生成的class的目錄

5.  java代碼、c代碼、so方法之間的聯繫

n  你的應用的java源代碼中要聲明一個或多個方法,這些方法前面需有'native'關鍵字,這代表它們被本地代碼實現。如:

public native String  stringFromJNI();

n  你必須提供本地的共享庫(.so),庫中包含這些方法的實現。將這個庫打包你的.apk中。這個庫的命名必須符合標準的Unix命名規則,也就是:lib<something>.so這種形式,例如:

libhello-jni.so

n  而且還要包含一個標準的JNI入口,例如:

static {

        System.loadLibrary("hello-jni");

    }

n  c函數生命應該按照以下規則命名,以說明函數是屬於哪一個java類的

java_目錄_目錄_方法名()例如:

 

jstring Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env, jobject thiz )

以上函數,是一個java類的成員函數,這個類必須是在com\example\hellojni包下,類名必須是HelloJni

方法名必須是stringFromJNI(),沒有參數

這是由於java是面向對象的語言,因此so中實現的全部全局函數應該是java的某個成員方法

 

n  JNIEnv* env, jobject thiz

2個參數是全部jni函數必須的,只有這2個參數的函數,表示無參數的成員函數,帶有 3個參數就表示成員函數有1個參數,依次類推

 

n  JNIEXPORTJNICALL在提供android應用調用的so代碼中不是必須的

加上兼容性更好

JNIEXPORT jstring JNICALL Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,jobject thiz );

6.  ndk能不能直接開發java

不知道,未研究,有興趣的能夠深刻研究,可以實現類成員函數,已經足夠

7.  so中能不能調用其它 .so.a

理論上能夠,但未驗證,能夠自行驗證,若是是so,須要將so文件一塊兒打包進apk,若是是.a文件,應該不須要打包進apk

8.  ndk適合開發哪些模塊

如下爲我的理解

n  首先ndk未提供ui以及事件處理的api,因此作android開發不可能使用純c/c++,應用主體應該仍是android sdk使用java開發

n  其次so的反編譯難度比android應用的java代碼要難上不少,,因此ndk能夠用於開發一些須要保密代碼,防止反編譯泄露機密算法邏輯等

n  觀察ndk支持的庫,能夠看到,ndk適合作一些算法模塊,提升效率,支持libc也能夠實現通訊模塊,增強通訊的安全性

相關文章
相關標籤/搜索