簡單實現Android NDK編譯jni呼叫動態庫開發
首先我們知道再次熟悉一下NDK的基本知識,Android平臺從誕生起,就已經支援C、C++開發。眾所周知,Android的SDK基於Java實現,這意味著基於Android SDK進行發的第三方應用都必須使用Java語言。但這並不等同於“第三方應用只能使用Java”,谷歌改良了ndk的開發流程,對於Windows環境下NDK的開發,Google在釋出之初就提出過,開發支援jni程式設計方式,也就意味著我們在開發的過程中可以呼叫自己的第三方動態庫了,不管是用c寫的還是c++寫的都行,那就有人要問的,為什麼要多此一舉,原因很簡單,越接近底層的程式碼,其耦合性機越強,執行效率也就更高,方便我們處理一下相對比較繁瑣的邏輯功能,
本部落格將的是NDK版本是人r10e,目前最新的NDK版本貌似是r11了,至於r7之前的版本需要安裝Cvgwin才能使用,既然有更高階的,那就何必講情懷呢不是,因為高版本的NDK提供了一個ndk-build.cmd的指令碼,可以直接利用這個指令碼編譯,而不需要使用Cygwin了。只需要為Eclipse Android工程新增一個Builders,而為Eclipse配置的builder,
其實就是在執行Cygwin,然後傳遞ndk-build作為引數,這樣就能讓Eclipse自動編譯NDK了,廢話不多說開始吧!
工欲善其事必先利其器,首先得配置好NDK開發環境:
1.我自己下載安裝NDK-r10e版本,現在可以下載更高階的r11了,下面提供下載地址:http://developer.android.com/sdk/ndk/index.html
2開啟我們的Eclipse(本人對Studio開發不是很熟悉,目前還在堅持著),新建一個Android工程,在工程目錄testNdk下新建jni資料夾,該資料夾就用來儲存NDK需要編譯的檔案程式碼比如.mk檔案
1.1 點選新建專案右鍵Properties->Builders->New或者Project->Properties->Builders->New,新建一個Builder。
1.2 彈出視窗如下,在彈出的【Choose configuration type】對話方塊,選擇【Program】,點選【OK】:
1.3 在彈出的【Edit Configuration】對話方塊中,配置選項卡【Main】。 在“Name“中輸入新builders的名稱,名字可以隨意取,任性點就好。接下來就是在“Location”中輸入nkd-build.cmd的路徑,是不是對這個檔案很陌生,這個檔案的來源是之前下載的NDKr10解壓後的中的檔案,可以自己設定路徑也可以點選Browser File System 找到解壓後的檔案路徑,這個建議放在根目錄下面,路徑不能有空格和中文,否則會編譯不通過,同樣的選在Working Diretcoty時可以選擇Worksapce 的專案位置,也可以點選Browse Workspace來選擇專案TestNDK的絕對路徑,如下圖:
1.4繼續在這個【Edit Configuration】對話方塊中,配置選項卡【Refresh】。
如下圖勾選“Refresh resources upon completion”,
勾選“The entire workspace”,
勾選“Recuresively include sub-folders”。
1.5 繼續在【Edit Configuration】對話方塊中,配置選項卡【Build options】。
勾選“After a “Clean””,(勾選這個操作後,如果你想編譯ndk的時候,只需要clean一下專案 就開始交叉編譯)
勾選“During manual builds”,
勾選“During auto builds”,
勾選“Specify working set of relevant resources”。如圖下圖
注意這個時候上面會提示有錯誤,那是因為你沒有選擇要關聯的工程,此時點選點選“Specify Resources…”勾選testNdk工程中新建的“jni“目錄,點選”finish“。 點選“OK“,完成配置。 如圖
到此點選finish、回去點選OK就算是配置完成了,接下來就開始試試行還是不行咯。
1.第一步就是在testNdk工程中新建一個JniTest.java的class類(為了呼叫C/C++程式碼),其內容如下:
package com.ndk.test;
public class JniTest{
static public native String AddStr(String strA, String strB);
static public native int AddInt(int a, int b);
}
2.生成 .h 的c++標頭檔案
(1)用cmd命令定位到JniTest.java所在目錄,輸入“javac JniTest.java“後回車,生成JniTest.class檔案
(如果是用的Eclipse建的工程,在testNdk\bin\classes\com\ndk\test目錄下就已經有JniTest.class檔案了)。
(2)將JniTest.class拷貝到testNdk\bin\classes\com\ndk\test目錄,將cmd命令定位到testNdk\bin\classes目錄,
輸入”javah com.ndk.test.JniTest.class“後回車,在testNdk\bin\classes目錄下就生成了C++標頭檔案com_ndk_test_JniTest.h
com_ndk_test_JniTest.h的檔案內容如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_ndk_test_JniTest */
#ifndef _Included_com_ndk_test_JniTest
#define _Included_com_ndk_test_JniTest
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_ndk_test_JniTest
* Method: AddStr
* Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_ndk_test_JniTest_AddStr
(JNIEnv *, jclass, jstring, jstring);
/*
* Class: com_ndk_test_JniTest
* Method: AddInt
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_com_ndk_test_JniTest_AddInt
(JNIEnv *, jclass, jint, jint);
#ifdef __cplusplus
}
#endif
#endif
3.在jni目錄下新建一個Android.mk檔案,其內容如下
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := TestNdk
LOCAL_SRC_FILES := com_ndk_test_JniTest.c
include $(BUILD_SHARED_LIBRARY)
4. 將剛剛手動生成的com_ndk_test_JniTest.h拷貝到TestNdk工程的jni目錄下,
然後新建一個com_ndk_test_JniTest.c檔案完成標頭檔案中函式的實現,其內容如下
(本來想寫兩個方法的,現在只講解第一個方法,返回一個字串“HelloWorld from JNI ”,
另一個方法是一個a+b的運算,方法寫到這裡,感興趣的可以自己去研究):
com_ndk_test_JniClient.c
#include "com_ndk_test_JniTest.h"
#include <stdlib.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C"
{
#endif
/*
* Class: com_ndk_test_JniTest
* Method: AddStr
* Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_ndk_test_JniTest_AddStr
(JNIEnv *env, jclass arg, jstring instringA, jstring instringB)
{
jstring str = (*env)->NewStringUTF(env, "HelloWorld from JNI !");
return str;
}
/*
* Class: com_ndk_test_JniTest
* Method: AddInt
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_com_ndk_test_JniTest_AddInt
(JNIEnv *env, jclass arg, jint a, jint b)
{
return a + b;
}
#ifdef __cplusplus
}
#endif
此刻,當編輯com_ndk_test_JniTest.c並儲存後,project下的—clean 一下工程,
就可以看到TestNkd工程下的obj/local/armeabi目錄下將自動生成libTestNdk.so庫。
5.在TestNdkActivity.java中完成對JniClient.java中函式的呼叫(首先靜態載入動態連結so庫)
package com.ndk.test;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class TestNdkActivity extends Activity {
static {
System.loadLibrary("TestNdk");
}
/** Called when the activity is first created. */
super.onCreate(savedInstanceState);
// setContentView(R.layout.main);
//第一個方法傳入的兩個引數沒有做操作,直接返回hello jni,不用管
String str = JniClient.AddStr("test", "test");
//第二個方法暫時不實現
// int iSum = JniClient.AddInt(5, 2);
// String strSum = "5 + 7 = " + iSum;
TextView tv1 = new TextView(this);
tv1.setText(str);
setContentView(tv1);
}
}
相關文章
- Android:JNI與NDK(二)交叉編譯與動態庫,靜態庫Android編譯
- Android NDK祕籍--編譯靜態庫、呼叫靜態庫Android編譯
- Android Studio NDK開發-JNI呼叫Java方法AndroidJava
- Android Studio NDK開發:JNI呼叫Java函式AndroidJava函式
- [Android開發]Mac下NDK開發(JNI)AndroidMac
- JNI/NDK開發指南(9):JNI呼叫效能測試及優化優化
- Android NDK開發之JNI基礎Android
- Android NDK隱藏jni動態庫的內部符號表Android符號
- Eclipse自動編譯NDK/JNI的三種方法Eclipse編譯
- java呼叫c++動態庫之jni呼叫JavaC++
- JNI/NDK開發指南(1):JNI開發流程及HelloWorld
- Android NDK開發之旅14 JNI 快取策略Android快取
- Android Studio ndk-Jni開發詳解Android
- Android 基於ffmpeg開發簡易播放器 - NDK交叉編譯ffmpegAndroid播放器編譯
- JNI/NDK開發指南(開山篇)
- Andorid Studio NDK 開發 – 編譯 OpenSSL 類庫編譯
- Andorid Studio NDK開發-編譯OpenSSL類庫編譯
- android NDK 交叉編譯Android編譯
- Android NDK開發之旅14 JNI 異常處理Android
- JNI呼叫c動態連結庫函式程式碼實踐函式
- 關於Android NDK中呼叫第三方的動態庫Android
- Android NDK開發掃盲及最新CMake的編譯使用Android編譯
- ndk-build 編譯多個CPU架構的動態連結庫UI編譯架構
- 使用NDK編譯含JNI的Android專案常見問題解決方案編譯Android
- Android JNI實現Java與C/C++互相呼叫,以及so庫的生成和呼叫(JNI方式呼叫美圖秀秀so)AndroidJavaC++
- JNI學習筆記之ndk-build手動編譯並整合流程筆記UI編譯
- JNI/NDK開發指南(8):呼叫構造方法和父類例項方法構造方法
- Android NDK祕籍--淺析靜態庫和動態庫Android
- JNI/NDK開發指南(4):字串處理字串
- Windows下搭建Android NDK開發環境及命令列編譯WindowsAndroid開發環境命令列編譯
- Android NDK開發之旅11 JNI JNI資料型別與方法屬性訪問Android資料型別
- 編譯lua動態庫編譯
- libusb android ndk編譯--編譯mipsAndroid編譯
- JNI原始碼分析(並實現JNI動態註冊)原始碼
- Android NDK祕籍--初識NDK、JNI、Makefile/CMakeAndroid
- Android Studio NDK:二、JNI 返回JAVA 實體AndroidJava
- Mac下安裝NDK,進行JNI開發Mac
- Android JNI開發系列之Java與C相互呼叫AndroidJava