Android JNI和NDK學習(09)--JNI執行個體二 傳遞類對象

來源:互聯網
上載者:User

標籤:onload   --   代碼   zip   ring   java   assert   根據   檔案   

1 應用程式層代碼

NdkParam.java是JNI函數的調用類,它的代碼如下:

 
package com.skywang.ndk;import android.app.Activity;import android.os.Bundle;import android.util.Log;public class NdkParam extends Activity {    public static final String TAG="skywang--NdkParam";    /** Called when the activity is first created. */    private Person person=null;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);                Log.d(TAG, "on create.");        person = new Person();        for (int i=0; i<3; i++) {            getPersonInfoByIndex(person, i);            Log.d(TAG, "person["+i+"] -- "+person);        }    }        // jni中註冊的方法    private native int getPersonInfoByIndex(Person person, int index);    static {        // 載入本地libndk_load.so庫檔案        System.loadLibrary("ndk_param");    }}
 

 

Person.java是用來在Java和JNI之間傳遞的資料類,它的代碼如下:

 
package com.skywang.ndk;public class Person {        private String  mName;                         private int     mAge;    private float   mHeight;        public String toString(){        return "mName:"+mName+", mAge:"+mAge+", mHeight:"+mHeight;    }}
 

 

2 JNI層代碼

ndk_param.c是實現並註冊JNI的檔案,它的代碼如下:

 
#include <stdlib.h>#include <string.h>#include <stdio.h>#include <jni.h>#include <assert.h>// 擷取數組的大小# define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))// 指定要註冊的類,對應完整的java類名#define JNIREG_CLASS "com/skywang/ndk/NdkParam"#define JNIPAR_CLASS "com/skywang/ndk/Person"// 引入log標頭檔#include <android/log.h>  // log標籤#define  TAG    "hello_param"// 定義info資訊#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG,__VA_ARGS__)// 定義debug資訊#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)// 定義error資訊#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,TAG,__VA_ARGS__)// jfieldID結構體,用於儲存類“Person.java”的filedIDstruct PersonOffsets{    jfieldID    name;    jfieldID    age;    jfieldID    height;} gPersonOffsets;// 與“Person.java”對應的結構體,用於儲存資料,並將資料賦值給Person.java的成員typedef struct tagPerson{    char    mName[10];    int     mAge;    float   mHeight;}Person;// 定義了3個Personstatic Person gPersons[] = {    {"skywang", 25, 175},    {"eman"   , 30, 166},    {"Dan"    , 51, 172},};#define GPERSON_NUM NELEM(gPersons)/*  * 根據index擷取Person資訊。 * 參數說明: *         env : JNI 介面指標。 *        claszz : Java 類對象。 *        person : 輸入參數,java對象 *        index : 輸入參數,序號。 */JNIEXPORT jint JNICALL getPersonInfoByIndex(JNIEnv *env, jobject clazz, jobject person, jint index){    // 若index無效,則直接返回-1。    if ((int)index<0 || (int)index>=GPERSON_NUM)        return -1;    // 將Person數組(gPersons)中的第index個成員賦值給pPerson指標    Person *pPerson = &gPersons[index];    // 設定java對象person的mName    jstring name = (*env)->NewStringUTF(env, pPerson->mName);    (*env)->SetObjectField(env, person, gPersonOffsets.name, name);    // 設定java對象person的mAge    (*env)->SetIntField(env, person, gPersonOffsets.age, pPerson->mAge);    // 設定java對象person的mHeight    (*env)->SetFloatField(env, person, gPersonOffsets.height, pPerson->mHeight);    LOGD("%s index-%d  mName:%s, mAge:%d, mHeight:%f\n",             __func__, index, pPerson->mName, pPerson->mAge, pPerson->mHeight);    return 0;}// 初始化函數,用於擷取Java中各個成員對應的fieldID。static void nativeClassInit (JNIEnv *env){       jclass personClass = (*env)->FindClass(env, JNIPAR_CLASS);           // 擷取Person的mName成員對應的FieldID,並儲存到gPersonOffsets中    gPersonOffsets.name     = (*env)->GetFieldID(env, personClass, "mName"  , "Ljava/lang/String;");            // 擷取Person的mAge成員對應的FieldID,並儲存到gPersonOffsets中    gPersonOffsets.age      = (*env)->GetFieldID(env, personClass, "mAge"   , "I");    // 擷取Person的mHeight成員對應的FieldID,並儲存到gPersonOffsets中    gPersonOffsets.height   = (*env)->GetFieldID(env, personClass, "mHeight", "F");}// Java和JNI函數的綁定表static JNINativeMethod method_table[] = {    { "getPersonInfoByIndex", "(Lcom/skywang/ndk/Person;I)I", (void*)getPersonInfoByIndex },//綁定};// 註冊native方法到java中static int registerNativeMethods(JNIEnv* env, const char* className,        JNINativeMethod* gMethods, int numMethods){    jclass clazz;    clazz = (*env)->FindClass(env, className);    if (clazz == NULL) {        return JNI_FALSE;    }    if ((*env)->RegisterNatives(env, clazz, gMethods, numMethods) < 0) {        return JNI_FALSE;    }    return JNI_TRUE;}int register_ndk_param(JNIEnv *env){    nativeClassInit(env);    // 調用註冊方法    return registerNativeMethods(env, JNIREG_CLASS,            method_table, NELEM(method_table));}// JNI_OnLoad在jni註冊時,會被回調執行。JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved){    JNIEnv* env = NULL;    jint result = -1;     if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {        return result;    }       register_ndk_param(env);    // 返回jni的版本    return JNI_VERSION_1_4;}
 

 

Android.mk的代碼如下:

 
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE    := ndk_paramLOCAL_SRC_FILES := ndk_param.c# 添加對log庫的支援LOCAL_LDLIBS:=-L$(SYSROOT)/usr/lib -llog#  若產生static的.a,只需添加 LOCAL_LDLIBS:=-llog include $(BUILD_SHARED_LIBRARY)LOCAL_PATH := $(call my-dir)
 

 

3 運行工程

logcat資訊如下:

 
D/skywang--NdkParam: on create.D/hello_param: getPersonInfoByIndex index-0  mName:skywang, mAge:25, mHeight:175.000000D/skywang--NdkParam: person[0] -- mName:skywang, mAge:25, mHeight:175.0D/hello_param: getPersonInfoByIndex index-1  mName:eman, mAge:30, mHeight:166.000000D/skywang--NdkParam: person[1] -- mName:eman, mAge:30, mHeight:166.0D/hello_param: getPersonInfoByIndex index-2  mName:Dan, mAge:51, mHeight:172.000000D/skywang--NdkParam: person[2] -- mName:Dan, mAge:51, mHeight:172.0
 

 

點擊下載:“原始碼

 

Android JNI和NDK學習(09)--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.