最近一段時間在做native層的開發,把一些經驗和技巧記錄下來,希望對大家有幫助。本教程以step-by-step的形式給正處入門階段的native開發新手提供指引。
導言:在進行Android開發的過程中,在一些對性能要求較高的場景,例如圖像處理,視音頻編解碼等,需要使用到native代碼以提高運行效率。本教程將在native層進行加法運算和字符串連接,通過這個簡單的例子闡述使用eclipse編譯運行ndk代碼的過程。
注:JNI基礎知識不在本文的討論範圍之內,推薦瀏覽oracle的幫助文檔進行系統學習
開發環境:
Adt-bundle(ver:21.1.0) 下載地址:https://developer.android.com/sdk/index.html
Ndk(ver:r8b) 下載地址:https://developer.android.com/tools/sdk/ndk/index.html
示例工程下載地址:https://github.com/ilzc/Code/tree/master/jni
步驟詳解:
1、 配置ndk路徑
打開Eclipse後,點擊菜單欄的Project->Preferences打開Preferences窗口,點擊左側Android->NDK選項,在右側NDK Location填入ndk的路徑
2、 創建工程並增加native支持
點擊菜單欄的File->New->Android Application Project創建Android工程。
創建完畢後,在PackageExplorer中右鍵點擊剛纔新建的Android項目,選擇Android Tools->Add Native Support,按下圖填寫,點擊確認後,工程目錄下會增加jni目錄,jni目錄下有test.cpp和Android.mk。
3、 編寫jave層的jni接口
創建一個Java類,類名爲Jni
編寫加載庫的代碼,並添加兩個native方法
- package com.mylzc.jni;
- public class Jni {
- static {
- System.loadLibrary("test");//加載庫 libtest.so
- }
- public static native int plus(int a, int b);//對應native層的Java_com_mylzc_jni_Jni_plus函數
- public static native String getString(String a, String b);//對應native層的Java_com_mylzc_jni_Jni_getString函數
- }
4、 編寫native層的代碼
- #include <jni.h>
- #include "stdlib.h"
- extern "C" {
- jint Java_com_mylzc_jni_Jni_plus
- (JNIEnv *, jclass, jint x, jint y) {
- return x + y;//返回x+y的結果
- }
- jstring Java_com_mylzc_jni_Jni_getString
- (JNIEnv *env, jclass, jstring a, jstring b) {
- const char* str_a = env->GetStringUTFChars(a, 0);
- const char* str_b = env->GetStringUTFChars(b, 0);
- int len_a = strlen(str_a);
- int len_b = strlen(str_b);
- //concat string
- char* str_result = new char[len_a+len_b +1];
- strcpy(str_result, str_a);
- strcat(str_result,str_b);
- jstring jstr_result = env->NewStringUTF(str_result);//創建string對象
- delete[] str_result;
- env->ReleaseStringUTFChars(a, str_a);
- env->ReleaseStringUTFChars(b, str_b);
- return jstr_result;//返回ab字符串連接之後的結果
- }
- }
5、 編寫Android.mk
- LOCAL_PATH := $(call my-dir) #指定源文件目錄
- include $(CLEAR_VARS) #清空變量
- LOCAL_MODULE := test #模塊名稱,對應編譯出libtest.so
- LOCAL_SRC_FILES := test.cpp #指定要編譯的源文件
- include $(BUILD_SHARED_LIBRARY) #指定編譯動態鏈接庫
6、 編譯運行
編譯:在Package Explorer視窗,右鍵點擊jni項目,選擇Build Project編譯項目,編譯成功後,在工程libs->armeabi目錄下可以看到libtest.so。
運行:在Package Explorer視窗,右鍵點擊jni項目,選擇Run As->Android Application運行工程。
最後,我們可以在logcat中可以看到打印結果: