① 如何將debug版本的so庫變成release版本
由於Smart_Gis安卓客戶端的需要,所以需要把gdal_2.3.1庫編譯成安卓平台Arm64_v8a版本的.so庫。由於要求是Android NDK版本 12以上,Android API 21以上的支持。
所以在本次編譯過程中全部需要使用64位的操作系統,NDK及編譯器,編譯環境為 操作系統:Ubuntu 16.04 LTS,安卓NDK版本:android-ndk-r14b,geos, proj。
1,最近遇到了之前編譯的geos, proj, skia, gdal庫都為debug版本,本人也沒有特意的去驗證,但是由於項目上線發布的原因,需要將所有的依賴的庫發布成release版本的,一來可以增加庫的穩定性,二來可以減小體積。
2,由於 gdal 庫在編譯成release版本的過程中可以參考我的gdal庫安卓平台編譯這篇文章,並在Application.mk文件裡面增加 APP_OPTIM := release 然後 ndk-build命令進行編譯就行了,如何驗證生成的庫是不是debug版本的呢?
在庫目錄下執行 readelf -S + 文件名 ,在列印出的信息中如果能查看到有debug字元即是debug版本。
3,到這一步我們需要找到我們打開我們編譯的工具鏈的位置,找到strip這個可執行程序,比如說 GCC存儲目錄或者本人的Android 交叉編譯工具鏈的位置。然後找到存儲.so庫的目錄下並復制當前目錄加上需要裁剪的庫名到工具鏈strip存放目錄下,
如下圖所示並回車。
4,再次查看SO庫並會發現該庫的體積縮小了很多,並使用readelf -S + 庫名列印出來的信息沒有debug字元。
② 如何用ndk生成64位或者32位的so庫文件
-lcrypto是缺少庫libcrypto.so吧\r\n你這用什麼系統編的啊為什麼執行命令看是linux 底下還有D盤\r\n \r\n程序里也有錯誤啊\r\njni\/OpensslWapper.cpp:102: error: undefined reference to 'BN_bn2hex'
③ android開發,怎麼使用ndk編譯成.so文件
一、首先下載android-ndk,官方網站是:http://developer.android.com/tools/sdk/ndk/index.html
目前最新的版本是android-ndk-r8e-windows-x86.zip,下載地址:
http://dl.google.com/android/ndk/android-ndk-r8e-windows-x86.zip
下載後把壓縮包解壓出來,例如:D:\ndk,目錄下的ndk-build.cmd就是用來編譯的批處理命令。
二、編譯,打開cmd命令行窗口,cd進入目錄:D:\ndk\samples\hello-jni,
然後執行命令:D:\ndk\ndk-build.cmd(如果設置過環境變數則直接使用ndk-build.cmd)來編譯hello-jni,如果沒有錯誤會輸出:
Gdbserver : [arm-linux-androideabi-4.6] libs/armeabi/gdbserver
Gdbsetup : libs/armeabi/gdb.setup
"Compile thumb : hello-jni <= hello-jni.c
SharedLibrary : libhello-jni.so
Install : libhello-jni.so => libs/armeabi/libhello-jni.so
三、創建android應用程序並使用so文件
打開eclipse創建一個android應用程序HelloJni,默認的com.example.hellojni包下面有一個MainActivity.java,
在此包下添加一個HelloJni.java,
④ ndk編譯生成so
本文講述使用Android 的ndk-build來編譯生成so庫,在命令行中編譯。編譯後的so庫可以調用。
環境問題略過,請自行網路或谷歌安裝ndk。
新建文件夾/cn/scnu
並在文件夾中創建java 文件:
該命令會編譯java文件並在build目錄下生成,然後我們打開build目錄
然後我們使用javah命令:
然後會生成一個.h頭文件,我們打開這個頭文件看看:
可以看到這裡面只有一個函數,這個函數返回一個整形,和前面的java頭文件對應。
接下來我們另外創建一個Test文件夾,在Test文件夾下創建jni目錄,然後將剛才生成的頭文件拷貝進來。
然後我們創建JNITest.c文件,文件內容如圖:
這個文件的主要內容就是調用頭文件並實現頭文件中的方法,我們返回了1024。
LOCAL_MODULE 就是我們要生成的so,LOCAL_SRC_FILES就是編譯的文件
這里就表示我們要生成的so庫的CPU架構。
使用命令行進入到Test目錄下,即jni的根目錄處,然後打命令:
結果如圖,然後我們就可以在libs目錄下發現生成的so庫了。
⑤ 如何定位Android NDK開發中遇到的錯誤
Android NDK中的錯誤定位對很多開發者來說是一件頭疼的事,本文通過一個Demo程序詳細講解了NDK的錯誤是如何產生的,以及如何通過命令行工具定位NDK的問題所在。
Android NDK是什麼?
Android NDK 是在SDK前面又加上了「原生」二字,即Native Development Kit,因此又被Google稱為「NDK」。眾所周知,Android程序運行在Dalvik虛擬機中,NDK允許用戶使用類似C / C++之類的原生代碼語言執行部分程序。NDK包括:
從C / C++生成原生代碼庫所需要的工具和build files;
將一致的原生庫嵌入可以在Android設備上部署的應用程序包文件(application packages files ,即.apk文件)中;
支持所有未來Android平台的一系列原生系統頭文件和庫。
為何要用到NDK?概括來說主要分為以下幾種情況:
代碼保護,由於APK的Java層代碼很容易被反編譯,而C/C++庫反匯難度較大;
在NDK中調用第三方C/C++庫,因為大部分的開源庫都是用C/C++代碼編寫的;
便於移植,用C/C++寫的庫可以方便地在其他的嵌入式平台上再次使用。
Android JNI與NDK的關系
Java Native Interface(JNI)標準是Java平台的一部分,它允許Java代碼和其他語言寫的代碼進行交互。JNI是本地編程介面,它使得在Java虛擬機(VM)內部運行的Java代碼能夠與用其它編程語言(如C、C++和匯編語言)編寫的應用程序和庫進行交互操作。
簡單來說,可以認為NDK就是能夠方便快捷開發.so文件的工具。JNI的過程比較復雜,生成.so需要大量操作,而NDK的作用則是簡化了這個過程。
哪些常見的NDK類型異常會導致程序Crash?
NDK編譯生成的.so文件作為程序的一部分,在運行發生異常時同樣會造成程序崩潰。不同於Java代碼異常造成的程序崩潰,在NDK的異常發生時,程序在Android設備上都會立即退出,即通常所說的閃退,而不會彈出「程序xxx無響應,是否立即關閉」之類的提示框。
NDK是使用C/C++來進行開發的,熟悉C/C++的程序員都知道,指針和內存管理是最重要也是最容易出問題的地方,稍有不慎就會遇到諸如內存無效訪問、無效對象、內存泄露、堆棧溢出等常見的問題,最後都是同一個結果:程序崩潰。例如我們常說的空指針錯誤,就是當一個內存指針被置為空(NULL)之後再次對其進行訪問;另外一個經常出現的錯誤是,在程序的某個位置釋放了某個內存空間,而後在程序的其他位置試圖訪問該內存地址,這就會產生無效地址錯誤。常見的錯誤類型如下:
初始化錯誤;
訪問錯誤;
內存泄露;
參數錯誤;
堆棧溢出;
類型轉換錯誤;
數字除0錯誤。
如何發現並解決NDK錯誤?
利用Android NDK開發本地應用時,幾乎所有的程序員都遇到過程序崩潰的問題,但它的崩潰會在logcat中列印一堆看起來類似天書的堆棧信息,讓人舉足無措。單靠添加一行行的列印信息來定位錯誤代碼做在的行數,無疑是一件令人崩潰的事情。在網上搜索「Android NDK崩潰」,可以搜索到很多文章來介紹如何通過Android提供的工具來查找和定位NDK的錯誤,但大都晦澀難懂。下面以一個實際的例子來說明,如何通過兩種不同的方法,來定位錯誤的函數名和代碼行。
首先,來看看我們在hello-jni程序的代碼中做了什麼(有關如何創建或導入工程,此處略),下面代碼中:在JNI_OnLoad()的函數中,即so載入時,調用willCrash()函數,而在willCrash()函數中, std::string的這種賦值方法會產生一個空指針錯誤。這樣,在hello-jni程序載入時就會閃退。我們記一下這兩個行數:在61行調用了willCrash()函數;在69行發生了崩潰。
下面我們來看看發生崩潰(閃退)時系統列印的logcat日誌:
如果你看過logcat列印的NDK錯誤的日誌就會知道,我省略了後面很多的內容,很多人看到這么多密密麻麻的日誌就已經頭暈腦脹了,即使是很多資深的Android開發者,在面對NDK日誌時也大都默默地選擇了無視。
其實,只要你細心的查看,再配合Google 提供的工具,完全可以快速地准確定位出錯的代碼位置,這個工作我們稱之為「符號化」。需要注意的是,如果要對NDK錯誤進行符號化的工作,需要保留編譯過程中產生的包含符號表的so文件,這些文件一般保存在$PROJECT_PATH/obj/local/目錄下。
第一種方法:ndk-stack
這個命令行工具包含在NDK工具的安裝目錄,和ndk-build及其他常用的一些NDK命令放在一起,比如在我的電腦上,其位置是/android-ndk-r9d/ndk-stack。根據Google官方文檔,NDK從r6版本開始提供ndk-stack命令,如果你用的之前的版本,建議還是盡快升級至最新的版本。使用ndk –stack命令也有兩種方式
實時分析日誌
在運行程序的同時,使用adb獲取logcat日誌,並通過管道符輸出給ndk-stack,同時需要指定包含符號表的so文件位置;如果你的程序包含了多種CPU架構,在這里需求根據錯誤發生時的手機CPU類型,選擇不同的CPU架構目錄,如:
當崩潰發生時,會得到如下的信息:
我們重點看一下#03和#04,這兩行都是在我們自己生成的libhello-jni.so中的報錯信息,因此會發現如下關鍵信息:
回想一下我們的代碼,在JNI_OnLoad()函數中(第61行),我們調用了willCrash()函數;在willCrash()函數中(第69行),我們製造了一個錯誤。這些信息都被准確無誤的提取了出來!是不是非常簡單?
先獲取日誌再分析
這種方法其實和上面的方法沒有什麼大的區別,僅僅是logcat日誌獲取的方式不同。可以在程序運行的過程中將logcat日誌保存到一個文件,甚至可以在崩潰發生時,快速的將logcat日誌保存起來,然後再進行分析,比上面的方法稍微靈活一點,而且日誌可以留待以後繼續分析。
第二種方法:使用addr2line和objmp命令
這個方法適用於那些不滿足於上述ndk-stack的簡單用法,而喜歡刨根問底的程序員們,這兩個方法可以揭示ndk-stack命令的工作原理是什麼,盡管用起來稍微麻煩一點,但可以稍稍滿足一下程序員的好奇心。
先簡單說一下這兩個命令,在絕大部分的Linux發行版本中都能找到他們,如果你的操作系統是Linux,而你測試手機使用的是Intel x86系列,那麼你使用系統中自帶的命令就可以了。然而,如果僅僅是這樣,那麼絕大多數人要絕望了,因為恰恰大部分開發者使用的是Windows,而手機很有可能是armeabi系列。
在NDK中自帶了適用於各個操作系統和CPU架構的工具鏈,其中就包含了這兩個命令,只不過名字稍有變化,你可以在NDK目錄的toolchains目錄下找到他們。以我的Mac電腦為例,如果我要找的是適用於armeabi架構的工具,那麼他們分別為arm-linux-androideabi-addr2line和arm-linux-androideabi-objmp;位置在下面目錄中,後續介紹中將省略此位置:
假設你的電腦是Windows系統,CPU架構為mips,那麼你要的工具可能包含在一下目錄中:
接下來就讓我們來看看如何使用這兩個工具,下面具體介紹。
找到日誌中的關鍵函數指針
其實很簡單,就是找到backtrace信息中,屬於我們自己的so文件報錯的行。
首先要找到backtrace信息,有的手機會明確列印一行backtrace(比如我們這次使用的手機),那麼這一行下面的一系列以「#兩位數字 pc」開頭的行就是backtrace信息了。有時可能有的手機並不會列印一行backtrace,那麼只要找到一段以「#兩位數字 pc 」開頭的行,就可以了。
其次要找到屬於自己的so文件報錯的行,這就比較簡單了。找到這些行之後,記下這些行中的函數地址。
使用addr2line查找代碼位置
執行如下的命令,多個指針地址可以在一個命令中帶入,以空格隔開即可
結果如下:
從addr2line的結果就能看到,我們拿到了我們自己的錯誤代碼的調用關系和行數,在hello-jni.cpp的69行和61行(另外兩行因為使用的是標准函數,可以忽略掉),結果和ndk-stack是一致的,說明ndk-stack也是通過addr2line來獲取代碼位置的。
使用objmp獲取函數信息
通過addr2line命令,其實我們已經找到了我們代碼中出錯的位置,已經可以幫助程序員定位問題所在了。但是,這個方法只能獲取代碼行數,並沒有顯示函數信息,顯得不那麼「完美」,對於追求極致的程序員來說,這當然是不夠的。下面我們就演示一下怎麼來定位函數信息。
首先使用如下命令導出函數表:
在生成的asm文件中查找剛剛我們定位的兩個關鍵指針00004fb4和00004f58:
從這兩張圖可以清楚的看到(要注意的是,在不同的NDK版本和不同的操作系統中,asm文件的格式不是完全相同,但都大同小異,請大家仔細比對),這兩個指針分別屬於willCrash()和JNI_OnLoad()函數,再結合剛才addr2line的結果,那麼這兩個地址分別對應的信息就是:
相當完美,和ndk-stack得到的信息完全一致!
Testin崩潰分析如何幫開發者發現NDK錯誤
以上提到的方法,只適合在開發測試期間,如果你的應用或游戲已經上線,而用戶經常反饋說崩潰、閃退,指望用戶幫你收集信息定位問題幾乎是不可能的。這個時候,我們就需要用其他的手段來捕獲崩潰信息。
目前業界已經有一些公司推出了崩潰信息收集的服務,通過嵌入SDK,在程序發生崩潰時收集堆棧信息,發送到雲服務平台,從而幫助開發者定位錯誤信息。在這方面,國內的Testin和國外的crittercism都可以提供類似服務。
Testin從1.4版本開始支持NDK的崩潰分析,其最新版本已升級到1.7。當程序發生NDK錯誤時,其內嵌的SDK會收集程序在用戶手機上發生崩潰時的堆棧信息(主要就是上面我們通過logcat日誌獲取到的函數指針)、設備信息、線程信息等,SDK將這些信息上報至Testin雲服務平台,在平台進行唯一性的處理、並可以自定義時段進行詳盡的統計分析,從多維度展示程序崩潰的信息和嚴重程度;最新版本還支持用戶自定義場景,方便開發者定位問題所在。
從用戶手機上報的堆棧信息,Testin為NDK崩潰提供了符號化的功能,只要將我們編譯過程中產生的包含符號表的so文件上傳,就可以自動將函數指針地址定位到函數名稱和代碼行數。符號化之後,看起來就和我們前面在本地測試的結果是一樣的了,一目瞭然。而且使用這個功能還有一個好處:這些包含符號表的so文件,在每次開發者編譯之後都會改變,很有可能我們發布之後就已經變了,因為開發者會修改程序。在這樣的情況下,即使我們拿到了崩潰時的堆棧信息,那也無法再進行符號化了。我們可以將這些文件上傳到Testin進行符號化的工作,Testin會為我們保存和管理不同版本的so文件,確保信息不會丟失。
⑥ NDK版本與Android固件要求對應表
NDK版本與Android固件要求對應表
對於Android NDK版本來說,編譯出來的so文件對應運行的Android固件最小版本是有一定要求的,高版本的NDK編譯出的.so文件由於包含了一些新的特性,新特性可能在低版本的Android固件上無法運行,目前最新的對著表Android開發網總結如下
API Level 1 --- Android 1.0 不支持NDK
API Level 2 --- Android 1.1 不支持NDK
API Level 3 --- Android 1.5 NDK 1
API Level 4 --- Android 1.6 NDK 2
API Level 5 --- Android 2.0
API Level 6 --- Android 2.0.1
API Level 7 --- Android 2.1 NDK 3
API Level 8 --- Android 2.2 NDK 4
API Level 9 --- Android 2.3 NDK 5
API Level 10 --- Android 2.3.3
API Level 11 --- Android 3.0
API Level 12 --- Android 3.1 NDK 6
API Level 13 --- Android 3.2
API Level 14 --- Android 4.0.1 NDK 7
API Level 15 --- Android 4.0.3
從上面來看,在Android關鍵版本更新上,NDK加入了很多新的特性,從簡單的C/C++知道到兼容STL,再到硬體擴展等,使得Android更開放,更強大。
⑦ android ndk 怎樣調用第三方的so庫文件
問題描述:Android如何調用第三方SO庫;
已知條件:SO庫為Android版本連接庫(*.so文件),並提供了詳細的介面說明;
已了解解決方案:
1.將SO文件直接放到libs/armeabi下,然後代碼中System.loadLibrary("xxx");再public native static int xxx_xxx_xxx();接下來就可以直接調用xxx_xxx_xxx()方法;
2.第二種方案,創建自己的SO文件,在自己的SO文件里調用第三方SO,再在程序中調用自己的SO,這種比較復雜,需要建java類文件,生成.h文件,編寫C源文件include之前生成的.h文件並實現相應方法,最後用android NDK開發包中的ndk-build腳本生成對應的.so共享庫;
求解:
1.上面兩種方案是否可行?不可行的話存在什麼問題?
2.兩種方案有什麼區別?為什麼網上大部都是用的第二種方案?
3.只有一個*.so文件,並提供了詳細的介面說明,是否可在ANDROID中使用它?
首先要看這個SO是不是JNI規范的SO,比如有沒有返回JNI不直接支持的類型。也就是說這個SO是不是可以直接當作JNI來調用。如果答案是否定的,你只能選第二個方案。
如果答案是肯定的,還要看你是不是希望這個SO的庫直接暴露給JAVA層,如果答案是否定的,你只能選第二個方案,比如你本身也是一個庫的提供者。
一般如果你只有SO,就說明這個是別人提供給你的,你可以要求對方給你提供配套的JAVA調用文件。
1、這個要看這個SO是不是符合JNI調用的規范。還要看你自己的意願。
2、因為第二種方法最靈活,各種情況都可以實現。
3、可以
看能不能直接從JAVA調用的最簡單的方法就是看SO里的函數名是不是Java_XXX_XXX_XXX格式的
是就可以,你可以自己寫一個配套的JAVA文件,注意一下SO函數名和JAVA函數名的轉換規則,或者向SO提供方索要;
不是的話就選第二種方案吧。
1、檢查所需文件是否齊全
使用第三方動態庫,應該至少有2個文件,一個是動態庫(.so),另一個是包含
動態庫API聲明的頭文件(.h)
2、封裝原動態庫
原動態庫文件不包含jni介面需要的信息,所以我們需要對其進行封裝,所以我
們的需求是:將libadd.so 裡面的API封裝成帶jni介面的動態
3、編寫庫的封裝函數libaddjni.c
根據前面生成的com_android_libjni_LibJavaHeader.h 文件,編寫libaddjni.c,用
來生成libaddjni.so
Android中集成第三方軟體包(.jar, .so)
Android中可能會用到第三方的軟體包,這包括Java包.jar和Native包.so。jar包既可通過Eclipse開發環境集成,也可通過編譯源碼集成,看你的工作環境。
假定自己開發的程序為MyMaps,需要用到BaiMaps的庫,包括mapapi.jar和libBMapApiEngine_v1_3_1.so。
一、Eclipse中集成第三方jar包及.so動態庫
MyMaps工程下創建目錄libs以及libs/armeabi,把mapapi.jar放在的libs/目錄下,把libBMapApiEngine_v1_3_1.so放在libs/armeabi/下。
Eclipse中把第三方jar包mapapi.jar打包到MyMaps的步驟:
1. 右擊工程,選擇Properties;
2. Java Build Path,選擇Libraries;
3. Libraries頁面點擊右面按鈕「Add Library…」;
4. 選擇「User Library」,點擊「Next」;
5. 點擊「User Libraries」按鈕;
6. 在彈出界面中,點擊「New…」;
7. 輸入「User library name」,點擊「OK」確認;
8. 返回之後,選擇剛剛創建的User library,右面點擊「AddJARs」;
9. 選擇MyMaps/libs/下的mapapi.jar;
10. 確認,返回。
這樣,編譯之後,該jar包就會被打進MyMaps.apk中,libBMapApiEngine_v1_3_1.so也被打包在lib/armeabi/中。
程序運行過程中,libBMapApiEngine_v1_3_1.so被放在/data/data/<yourAppPackage>/lib/下,載入動態庫時系統會從程序的該lib/目錄下查找.so庫。
二、源碼中集成第三方集成jar包及.so動態庫
Android源碼中MyMaps放在packages/apps下。MyMaps下創建目錄libs以及libs/armeabi,並把mapapi.jar放在libs/,把libBMapApiEngine_v1_3_1.so放在libs/armeabi。
2.1 修改Android.mk文件
Android.mk文件如下:
[plain] view plain
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_STATIC_JAVA_LIBRARIES := libmapapi
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_PACKAGE_NAME := MyMaps
include $(BUILD_PACKAGE)
##################################################
include $(CLEAR_VARS)
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES :=libmapapi:libs/mapapi.jar
LOCAL_PREBUILT_LIBS :=libBMapApiEngine_v1_3_1:libs/armeabi/libBMapApiEngine_v1_3_1.so
LOCAL_MODULE_TAGS := optional
include $(BUILD_MULTI_PREBUILT)
# Use the following include to make our testapk.
include $(callall-makefiles-under,$(LOCAL_PATH))
1 集成jar包
LOCAL_STATIC_JAVA_LIBRARIES取jar庫的別名,可以任意取值;
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES指定prebuiltjar庫的規則,格式:別名:jar文件路徑。注意:別名一定要與LOCAL_STATIC_JAVA_LIBRARIES里所取的別名一致,且不含.jar;jar文件路徑一定要是真實的存放第三方jar包的路徑。
編譯用BUILD_MULTI_PREBUILT。
2 集成.so動態庫
LOCAL_PREBUILT_LIBS指定prebuilt so的規則,格式:別名:so文件路徑。注意:別名一般不可改變,特別是第三方jar包使用.so庫的情況,且不含.so;so文件路徑一定要是真實的存放第三方so文件的路徑。
編譯拷貝用BUILD_MULTI_PREBUILT。
2.2 加入到GRANDFATHERED_USER_MODULES
在文件user_tags.mk中,把libBMapApiEngine_v1_3_1加入到GRANDFATHERED_USER_MODULES中
[plain] view plain
GRANDFATHERED_USER_MODULES += \
… \
libBMapApiEngine_v1_3_1
user_tags.mk可以是build/core下的,也可以是$(TARGET_DEVICE_DIR)下的,推薦修改$(TARGET_DEVICE_DIR)下的。
2.3 編譯結果
MyMaps.apk編譯生成在out/target/proct/<YourProct>/system/app/下;
libBMapApiEngine_v1_3_1.so放在out/target/proct/<YourProct>/system/lib/下,這也是系統載入動態庫時搜索的路徑。
⑧ 使用NDK-R8版本編譯X86平台下使用的so文件時報錯。 什麼都不改去編譯arm平台正常。求高手指教~~
在android.mk文件中加入:
LOCAL_LDLIBS += -L$(NDK_ROOT)/sources/cxx-stl/stlport/libs/armeabi -lstlport_static
⑨ eclipse ndk生成so庫怎麼添加版本號
由於在原來的ADT的Eclipse環境中,用ndk_build工具生成了相應的各個.so庫文件之後,eclipse工具就會自動把這些庫導入到apk中。而Android Studio目前為止(0.86版本)還無法做到那麼自動,但是我們可以通過以下方式進行。 首先在Android Studio工
⑩ NDK開發的so文件到底能為應用程序做什麼事
下載後把壓縮包解壓出來,例如:D:\ndk,目錄下的ndk-build.cmd就是用來編譯的批處理命令。
二、編譯,打開cmd命令行窗口,cd進入目錄:D:\ndk\samples\hello-jni,
然後執行命令:D:\ndk\ndk-build.cmd(如果設置過環境變數則直接使用ndk-build.cmd)來編譯hello-jni,如果沒有錯誤會輸出:
Gdbserver : [arm-linux-androideabi-4.6] libs/armeabi/gdbserver
Gdbsetup : libs/armeabi/gdb.setup
"Compile thumb : hello-jni <= hello-jni.c
SharedLibrary : libhello-jni.so
Install : libhello-jni.so => libs/armeabi/libhello-jni.so
三、創建android應用程序並使用so文件
打開eclipse創建一個android應用程序HelloJni,默認的com.example.hellojni包下面有一個MainActivity.java,
在此包下添加一個HelloJni.java,