Android JNI開發

來源:互聯網
上載者:User

標籤:

概述

    在開發framework的時候有時會遇到需要自己開發JNI,以便使Java能夠調用自己底層開發的庫。網上的文章一般都是介紹如何通過命名規則及javah,使jni層函數與java層函數自動建立連結(Java虛擬機器通過命名規則建立),本文將講解如何動態註冊jni函數。

 

依賴庫及標頭檔

    先貼出Android.mk的代碼

 1 LOCAL_PATH :=$(call my-dir) 2 include $(CLEAR_VARS) 3  4 LOCAL_SRC_FILES := kiki_jni.cpp  5                    kiki_local.cpp  6  7 LOCAL_SHARED_LIBRARIES := libandroid_runtime  8                        libnativehelper  9                        liblog 10 11 #dependence12 LOCAL_REQUIRED_MODULES := 13 14 LOCAL_C_INCLUDES += $(JNI_H_INCLUDE) 15 16 #add micro define17 LOCAL_CFLAGS += 18 19 LOCAL_MODULE := liblearnjni_jni20 21 include $(BUILD_SHARED_LIBRARY)

    LOCAL_SHARED_LIBRARIES:需要的共用庫,在android中我們用刀libandroid_runtime及libnativehelper兩個。

    LOCAL_C_INCLUDES:需要的標頭檔包含,寫$(JNI_H_INCLUDE)即可。

    在Android的JNI架構中,一般會有一個JNI的cpp檔案用於溝通上層Java與底層Cpp,具體的商務邏輯實現會放在底層Cpp的另一個檔案中,因此這裡用kiki_jni.cpp類比JNI檔案橋,kiki_local.cpp類比實際實現邏輯的檔案。

    實際使用的標頭檔主要有:

#include <jni.h>#include <JNIHelp.h>#include "android_runtime/AndroidRuntime.h"#include "android_runtime/Log.h"

 

JNI註冊流程

    JNI註冊流程其實很簡單,主要分為三個步驟:

    1.實現JNI本地函數

    2.通過JNINativeMethod機構體將Java函數與本地函數一一關聯,實現映射表

    3.調用AndroidRuntime::registerNativeMethods方法註冊函數映射表

    那麼什麼時候註冊函數映射表呢?一般實現在jint JNI_OnLoad(JavaVM* vm, void* reserved)函數中。這個函數會在動態庫被載入後第一時間執行,因此一般會在裡面做一些初始化操作。具體代碼如下:

 1 using namespace android; 2  3 static const char* const kLearnJni = "android/kiki/LearnJni"; 4  5 static jint  6 android_kiki_LearnJni_helloJni(JNIEnv *env, jobject thiz, jstring ip, jint port) { 7     return getMagicNum(); 8 } 9 10 static JNINativeMethod gMethods[] = { 11     {   12         "helloJni",13         "(Ljava/lang/String;I)I",14         (void *)android_kiki_LearnJni_helloJni15     },  16 };17 18 int register_android_kiki_LearnJni(JNIEnv *env) {19     return AndroidRuntime::registerNativeMethods(env, kLearnJni, gMethods, NELEM(gMethods));20 }21 22 jint JNI_OnLoad(JavaVM* vm, void* reserved) {23     JNIEnv *env = NULL;24     jint res = -1; 25 26     if(vm -> GetEnv((void **) &env, JNI_VERSION_1_4) != JNI_OK) {27         ALOGE("ERROR: Get java env failed");28         goto bail;29     }   30 31     if(register_android_kiki_LearnJni(env) <= 0) {32         ALOGE("ERROR: LearnJni native registration failed");33         goto bail;34         35     }   36 37     res = JNI_VERSION_1_4;38     ALOGD("JNI library onload success");39 40 bail:41     return res;42 }

 

其他資訊

    每個Java進程有一個JavaVM,每個執行線程有一個JNIEnv,可以通過JavaVM擷取當前JNIEnv。JNIEnv的本質就是提供出來的JNI操作Java對象的方法和成員變數的API介面類。JNIEnv通過getMethod及get<Type>Field方法獲得Java對象的方法及成員變數,通過對應的call<Type>Method方法及set<Type>Field方法操作他們。

    Java函數在JNI中籤名對應如下:

 

    比較特殊的就是boolean轉為Z,long轉為J。

 

Android JNI開發

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.