編輯:關於Android編程
最近學習了一下NDK的開發, 就來分享一下.
對一個新鮮事物, 我們先解決的無非就是三件事情: 是什麼?為什麼?怎麼做?.
(英語:native development kit,簡稱NDK)是一種基於原生程序接口的軟件開發工具。通過此工具開發的程序直接以本地語言運行,而非虛擬機。因此只有java等基於虛擬機運行的語言的程序才會有原生開發工具包。[維基百科]
NDK是一系列工具的集合
NDK提供了一系列的工具,幫助開發者快速開發C(或C++)的動態庫,並能自動將so和java應用一起打包成apk。這些工具對開發者的幫助是巨大的.
NDK集成了交叉編譯器,並提供了相應的mk文件隔離CPU、平台、ABI等差異,開發人員只需要簡單修改mk文件(指出“哪些文件需要編譯”、“編譯特性要求”等),就可以創建出so。
NDK可以自動地將so和Java應用一起打包,極大地減輕了開發人員的打包工作。
上述文字致謝Devin Zhang提供理論支持
是什麼和為什麼我就先介紹到這兒, 接下來就具體看看如何進行NDK的開發
Android Studio 2.2.2 JDK1.7 API 24 Gradle 2.2.2請大家務必升級到AS 2.2以上版本, 因為這個版本升級了很多內容, 詳情請見 Android Studio 2.2 正式穩定版發布
大家可以直接打開SDK進行下載和安裝
由於NDK的工具包較大, 大家也可以選擇從網站中下載: http://wear.techbrood.com/tools/sdk/ndk/, 選擇自己對應的版本使用迅雷等工具下載即可, 不過通過這種方法一定要修改local.properties文件, 在裡面添加:
//後面改成自己下載後解壓的路徑名 ndk.dir=C\:\\Users\\Lulu\\AppData\\Local\\Android\\android-ndk-r13
關於CMake
CMakeList.txt 是腳本文件, 需要指定包含哪些源代碼; 可以寫一些條件語句, 實現不同的代碼包含 內部說明:
1). add_library 表示編譯一個代碼庫, 內部包含了代碼庫的名稱, 以及源代碼有哪些
接下來通過幾個案例來演示NDK的開發流程
新建工程, 選中Include C++ Support
vc/uLCDV4tH5u+G4+M7Sw8ew/Ln80rvQqczYtqi1xMq+wP20+sLrLCCw79b6ztLDx8DtveK6zcq508M8YnIgLz4NCjxpbWcgYWx0PQ=="NDK" src="/uploadfile/Collfiles/20161108/201611081014272006.png" title="\" />
點擊Finish, 如果出現圖示錯誤的肯定沒有好好看上面的 開發前准備
step1: 為了使代碼整潔, 咱們新建一個類 NativeHelper, 專門用於訪問C語言代碼的幫助類 並添加獲取Appkey的方法
public class NativeHelper { static { // 加載C代碼庫, 庫的名稱, 必須是CMakeLists.txt中指定的名稱 System.loadLibrary("native-lib"); } //獲取C中隱藏的AppKey public static native String getAppKey(); }
Note: 一定要添加上面的靜態代碼塊的內容, 否則無法加載C代碼庫
此時的getAppKey()方法標紅, 不用管它, 繼續….step2: 在cpp目錄下右擊創建C/C++ Source, 選擇Type, 並勾選 Create an associated hader, 為保持對應, 名字命名為: com_lulu_ndkdemo_NativeHelper, 此時會出現, 在cpp目錄下會出現兩個文件, 如圖:
step3: 在CMakeLists.txt中的add_library中添加依關系, 點擊同步
src/main/cpp/com_lulu_ndkdemo_NativeHelper.c
Note:
C代碼庫生成的名稱規則
1. 如果棧頂代碼庫名稱為 “nh” 那麼生成的文件必定是libnh.so
命名規則: lib庫名.so
2. System.loadLibrary(庫名); //此處不能包含前面的lib和後面的.sostep4: 在com_lulu_ndkdemo_NativeHelper.c文件中添加c語言代碼
#includeJNIEXPORT jstring JNICALL Java_com_lulu_ndkdemo_NativeHelper_getAppKey(JNIEnv *env, jclass type) { //測試代碼, 沒有任何意義 char* app_key = "5465465416948"; //生成 Java 中的字符串對象 //指針的指針 // env <=> JNINativeInterface** C語言 return (*env)->NewStringUTF(env, app_key); }
step5: 在MainActivity中獲取AppKey, 查看結果 -> 成功
String appKey = NativeHelper.getAppKey(); Log.d(TAG, "onCreate: appKey => " + appKey);
Note: Java 調用C/C++代碼
1. 任何一個類的方法, 如果聲明了native修飾符, 那麼就可以認為是一個C代碼;
2. 可以用對象, 類直接調用
3. 創建C/C++文件; 如果一個類中有一個native的方法, 那麼對應的C方法: Java_包名類名方法名(JNIEnv *env, …);
4. 當Java類中包含了native的方法, 那麼這個類必須寫一個靜態初初始化塊: System.loadLibrary(“庫名”)
接下來, 只簡單介紹核心代碼, 不再贅述
step1: 在com_lulu_ndkdemo_NativeHelper.c中添加:
JNIEXPORT void JNICALL Java_com_lulu_ndkdemo_NativeHelper_printLog(JNIEnv *env, jclass type, jstring str_) { const char *str = (*env)->GetStringUTFChars(env, str_, 0); //TODO: 顯示Android 的日志 // 調用Android的代碼 // 代碼需要調用系統的日志庫, 這個庫已經在 CMakeList.txt添加了e,因此可以直接調用 const char *tag = "NativeHelper"; //jstring -> char* jboolean b = JNI_FALSE; const char* txt = (*env)->GetStringUTFChars(env, str_, b); //打印log日志 __android_log_write(ANDROID_LOG_DEBUG, tag, txt); //釋放string (*env)->ReleaseStringUTFChars(env, str_, str); }
step2: NativeHelper中添加
//在C中打印log public static native void printLog(String str);
step3: MainActivity中調用
//打印C語言中的Log NativeHelper.printLog("測試Log");
Demo已上傳到github上, 歡迎大家Clone
至此, 咱們應該大致了解了一下NDK開發的簡單流程, 鄙人菜鳥, 希望拋磚引玉, “引”出更好的文章
本文還有下篇, 將再寫一些關於NDK開發的案例Demo, 希望大家喜歡和關注
前言 本文主要介紹在Android中怎樣來解析XML文件。主要采用的是SAX機制,SAX全稱為Simple API for XML,它既是一種接口,也是一個
Dagger 是一種android平台的依賴注入框架,是有一家專注於移動支付的公司,Square公司推出的庫,這家公司也推出了 其他在Android開發中常用庫:otto
Android計算器界面圖: 所定義的XML布局文件,主要用到的是TableLayout:
在研究如何實現Pushing功能期間,收集了很多關於Pushing的資料,其中有一個androidnp開源項目用的人比較多,但是由於長時間沒有什麼人去維護,聽說bug的幾