1. 程式人生 > >Android中JNI建立例項

Android中JNI建立例項

 參考文件:

Android通過JNI來實現Java層呼叫C層程式碼。當我們在進行NDK開發時候,並且提供Java層介面,則我們必須建立c程式碼,然後編譯*.so庫,編寫JNI中的程式碼,最後Java層通過System.loadLibrary()方法載入*.so動態庫,即可實現。

編寫一個具有*.so, jni , java整體模組,一般有個步驟:(1)編寫Java層程式碼,裡面主要實現兩個步驟,一個是定義native方法,另一個是呼叫System.loadLibrary()方法載入C層要寫的動態庫;(2)Java程式碼所生層的class檔案,使用javah命令生成JNI中所需的*.h

標頭檔案;(3)實現上面所生存的*.h標頭檔案;(4)編寫Android.mk檔案,生存*.so(5)編譯整個工程生成apk

第一:編寫Java檔案

根據我們需要實現的Java程式,來編寫native方法和呼叫System.loadLibrary()方法載入動態庫,一般開發Android工程我們都在Eclipse環境下,因此,這裡也在該環境下編寫一個Demo

packagecom.example.nativetest;

publicclassNativeClass {
static
{
System.loadLibrary("NativeClassJni");
}
privatestaticnativeintnativeGetResult(intsrc);
publicintgetResult(intsrc){
returnnativeGetResult(src);
}

}


當我們編寫好Java程式碼後,Eclipse會自動在工程bin目錄中生成對應的class檔案,裡面包含了所有Java檔案所生的.class檔案。

第二:由javah命令生成JNI中所需的*.h標頭檔案

在第一步中,我們知道在工程的bin/classes/*目錄裡有生成的.class檔案,這裡就需要使用javah命令將對應的NativeClass.class生成*.h檔案,我們進入到工程根目錄裡面,執行如下命令:

javah-classpath ./bin/classes -d jni com.example.nativetest.NativeClass

該命令解析如下:-classpath

選項表示工程Java檔案所生成的所有.class所在的目錄,必須指定bin/classes目錄下面,即所有.class所在的目錄,不能是它的子目錄或者父目錄,否則就會出現錯誤:error:cannot access com.example.nativetest.NativeClass ,這點非常重要。-djni表示在當前的目錄下新建一個jni資料夾,然後將生成的*.h檔案放入到該目錄中,因為測試當前目錄是工程的根目錄,因此,會在根目錄中新建jni資料夾;若無該選先,則生成的.h檔案會在當前目錄中。

當我們進入jni檔案中,就會發現所生成的標頭檔案com_exmaple_nativetest_NativeTest.h

/*DO NOT EDIT THIS FILE - it is machine generated */
#include<jni.h>
/*Header for class com_example_nativetest_NativeClass */

#ifndef_Included_com_example_nativetest_NativeClass
#define_Included_com_example_nativetest_NativeClass
#ifdef__cplusplus
extern"C" {
#endif
/*
*Class: com_example_nativetest_NativeClass
*Method: nativeGetResult
*Signature: (I)I
*/
JNIEXPORTjint JNICALL Java_com_example_nativetest_NativeClass_nativeGetResult
(JNIEnv*, jclass, jint);

#ifdef__cplusplus
}
#endif
#endif


第三:實現.h標頭檔案,編寫c/c++檔案

我們要在前面所生成的.h文加夾目錄中編寫c/c++檔案來實現該標頭檔案,*.c*.cpp檔案的名稱由使用者自己定義,但是必須要在Android.mk文加中的LOCAL_SRF_FILES指向該檔案即可,一般情況下,取和*.h相同的名字。

上面實現的.cpp檔案內容如下:

#include<jni.h>
#include<com_example_nativetest_NativeClass.h>
/*
*Class: com_example_nativetest_NativeClass
*Method: nativeGetResult
*Signature: (I)I
*/
JNIEXPORTjint JNICALL Java_com_example_nativetest_NativeClass_nativeGetResult
(JNIEnv* env, jclass obj, jint in)
{
returnin + in;
}

很多人在最終成功編譯so並載入so,java層呼叫native方法時會出現java.lang.UnsatisfiedLinkError這個異常.原因是就在第一行,這裡cc++是有些區別的,如果用c實現的話,只需要includejni.h即可,但是如果用c++實現,那麼必須要include你剛剛生成的.h檔案,而不是jni.h.雖然編譯可以通過,但是呼叫時你會發現報了java.lang.UnsatisfiedLinkError這個異常.原因就是java層沒找到對應的方法.還有就是cc++語法上的一些小區別,但這些錯誤是可以在編譯so期間發現的.

第四:編寫Android.mk檔案,生成*.so動態庫

當我們實現好.c或者.cpp檔案後,編寫Android.mk檔案,來生成動態庫,一般使用NDK工具進行生成,首先是下載ndk包,然後設計全域性變數,進入Android.mk資料夾中執行ndk編譯命令即可。

ndk編譯命令使用參考:

我們進入.c,.h, Android.mk所在的檔案下面,然後執行ndk編譯命令:

ndk-build

資訊如下:

[email protected]:~/workspace/NativeTest/jni$ndk-build

AndroidNDK: WARNING: APP_PLATFORM android-19 is larger thanandroid:minSdkVersion 8 in/home/archermind/workspace/NativeTest/AndroidManifest.xml

[armeabi]Compile++ thumb: NativeClassJni <=com_example_nativetest_NativeClass.cpp

[armeabi]StaticLibrary : libstdc++.a

[armeabi]SharedLibrary : libNativeClassJni.so

[armeabi]Install : libNativeClassJni.so =>libs/armeabi/libNativeClassJni.so


我們可以看到,在工程目錄libs生成了一個armeabi資料夾,裡面有一個libNativeClassJni.so檔案,就是NDK生成的動態庫,注意,這個名稱前面的lib是系統自動加上去的,在Java程式碼中的System.loadLibrary()中是不需要,即只是System.loadLibrary(NativeClassJni).

第五:編譯整個工程

.so庫編譯好之後,我們在Eclipse裡面對整個工程進行編譯,生成apk,匯入到Devices裡面即可執行。


相關推薦

AndroidJNI建立例項

 參考文件: Android通過JNI來實現Java層呼叫C層程式碼。當我們在進行NDK開發時候,並且提供Java層介面,則我們必須建立c程式碼,然後編譯*.so庫,編寫JNI中的程式碼,最後Java層通過System.loadLibrary()方法載入*.so

Android的Intent例項講解

Intent 是由動作,資料,分類,元件和擴充套件資訊等組成。 組成 屬性 設定屬性的方法 獲取屬性的方法 動作 Action setAction() getAction()

AndroidJNI使用詳解(4)---Java與C之間資料型別轉換

Jni中基本型別轉換對應的表格 Java型別 本地型別 說明 boolean jboolean 無符號,8位 byte jbyte

AndroidJNI使用詳解(3)---Android StudioSO檔案生成

Android中JNI使用詳解(2)---Android Studio中SO檔案生成 上一篇寫到過在Android Studio中配置NDK環境地址:Android Studio中NDK環境配置 這篇文章講解在Android Studio中

AndroidJNI使用詳解(2)---Android StudioNDK環境配置

Android Studio中的NDK環境配置 1、下載NKD 在Android Studio中選擇File----Settings----Appearance&Behavior---System Settings----Andr

AndroidJNI使用詳解(1)---EclipseNDK配置So檔案生成

1、NDK下載和配置 NDK下載地址:http://www.androiddevtools.cn/ NDK下載完成後,選擇Eclipse上方Window選單Preferences - Android - NDK 在NDK&nb

資料加密在Android 的使用例項 ---- 總篇

演算法可以看下博文:資料加密 ---- 總篇   應用例項: Android 中資料加密 ---- RSA加密 Android 中資料加密 ---- SHA加密 Android 中資料加密 ---- MD5加密 Android 中資料加密 ---- 3DES加密

AndroidJni學習總結--Jni列印log資訊

一、在jni中c++層進行log的列印 1、在需要使用log的cpp檔案中加入 #include <android/log.h> 2、在需要列印的地方直接呼叫 __android_log_print(ANDROID_LOG_INFO,"test","value is %

AndroidFragment建立

首先要為Fragment建立好xml和java程式並關聯在一起。 xml進行的是Fragment的介面設計(就像一個Activity)  Java程式中要繼承Fragment,建立Oncreate

如何在Android避免建立不必要的物件

在程式設計開發中,記憶體的佔用是我們經常要面對的現實,通常的記憶體調優的方向就是儘量減少記憶體的佔用。這其中避免建立不必要的物件是一項重要的方面。 Android裝置不像PC那樣有著足夠大的記憶體,而且單個App佔用的記憶體實際上是比較小的。所以避免建立

AndroidJNI呼叫過程簡述

1.安裝和下載cygwin,下載Android NDK; 2.在ndk專案中JNI介面的設計; 3.使用C/C++實現本地方法; 4.JNI生成動態連結庫.so檔案; 5.將動態連結庫複製到java工程,在Java工程中呼叫,執行Java工程即可。

AndroidJNI程式設計的那些事兒 【轉】

後續可能為需要加入一些特定的模組到android中,所以JNI還需繼續熟悉起來 首先說明,Android系統不允許一個純粹使用C/C++的程式出現,它要求必須是通過Java程式碼嵌入Native C/C++——即通過JNI的方式來使用本地(Native)程式碼。因此

史上最全面,最細的Androidlayout建立子資料夾

最近我在封裝android播放器 ,裡面的佈局巢狀比較多,layout檔案也比較多,所以想著能不能再layout資料夾下建立子資料夾,經過一系列的查閱與嘗試,最終還是完成了我想要的效果,在此分享給大家。先截圖來一波正確的操作:分解步驟:首先將專案以project目錄開啟1.在

Android如何建立xml檔案

SAX中想必大家對XML檔案讀取的方法已經比較熟悉了,在這裡我們就不多說了,直接說明如何將資訊寫成XML檔案,首先介紹Andoid SDK中的相關類。 類 說明 XmlSerializer Define an interface to serialziation

androidjni,記憶體優化,設計模式總結

studio使用jni步驟總結: 建立native方法 編譯一下生成class檔案 對應的class檔案生成.h檔案(也就是C語言的標頭檔案) 在main資料夾下建立jni目錄,然後將標頭檔案拷貝到裡面 在jni目錄下建立c檔案,並引入生成的標頭檔案,

Android反射機制解析 API介紹 建立private構造方法類例項 反射內部類 使用demo

反射 前言 相關知識點 編譯型語言和解釋型語言 動態型別語言和靜態型別語言 反射(Reflection) Class Class類API Constructor類 AP

Android關於JNI 的學習(一)對於JNIEnv的一些認識

else size 初步 jint 使用 包括 pri jnienv 就會 一個簡單的樣例讓我們初步地了解JNI的作用,可是關於JNI中的一些概念還是須要了解清楚,才可以更好的去利用它來實現我們想要做的事情。 那麽C++和Java之間的是怎樣通過JNI來進行互相調用的呢

android studio jni底層日誌的打印

添加 註意 erro ldl end 1.0 dto 字符 ati 1 添加ndk對log支持若需要添加ndk對log的支持,只需要通過以下2步即可實現。 1.1 修改Android.mk如生成的庫文件是“.so文件”,則在Android.mk中添加如下內容:LOCAL_L

JNI入門教程1---Android studio 下JNI程式設計例項並生成so庫

參考地址: https://www.cnblogs.com/jymblog/p/5526865.html                   https://www.jianshu.com/p/a

程式使用DirectShow技術報“COM元件建立例項失敗”

問題: 最近開發的功能中,使用DirectShow技術代替舊VFW,調取高拍儀或攝像頭為了相容大部分品牌裝置。 可以同事在給客戶機器安裝產品後,執行時系統提示“IClassFactory為CLSID為{51B4ABF3-748F-4E3B-A276-C828330E926A}的COM元件