zoukankan      html  css  js  c++  java
  • Android JNI 自定义对象为参数和返回值

    ndroid JNI 提供了很强大的支持,不仅可以采用基本类型做为参数和返回值,同时也支持自定义对象做为参数和返回值,以下举例说明。

    一、定义作为输入和返回的自定义类 (仅提供两个简单类型和一个打印函数)

    1. package com.example.jniexample; 
    2.  
    3. import android.util.Log; 
    4.  
    5. public class JNIParam { 
    6.     public int mInt; 
    7.     public String mString; 
    8.      
    9.     JNIParam(){ 
    10.         mInt    = 0; 
    11.         mString = "0";   
    12.     } 
    13.      
    14.     public void print(String tag){ 
    15.         Log.d(tag, String.format("print: mInt=%d, mString=%s", mInt, mString)); 
    16.     } 

    二. 定义和JNI通信的java封装 

    功能:测试输入参数和返回值都为自定义对象的本地方法,同时提供必要的调试打印

    1. package com.example.jniexample; 
    2.  
    3. public class JNIParamTest { 
    4.     private final String TAG = "JNIParamTest"; 
    5.      
    6.     static { 
    7.         System.loadLibrary("JNIParamTest"); 
    8.     }; 
    9.  
    10.     public void runParamTest(){ 
    11.         JNIParam paramIn = new JNIParam(); 
    12.         paramIn.print(TAG); 
    13.          
    14.         JNIParam paramOut = doTest(paramIn); 
    15.         if( paramOut != null ) paramOut.print(TAG); 
    16.     } 
    17.      
    18.     //JNI  
    19.     private native JNIParam doTest(JNIParam paramIn); 

    三、实现JNI的本地实现

    a. 头文件 (JNIParamTest.h)

    1. /* DO NOT EDIT THIS FILE - it is machine generated */ 
    2. #include <jni.h>  
    3. /* Header for class com_example_jniexample_JNIParamTest */ 
    4.  
    5. #ifndef _Included_com_example_jniexample_JNIParamTest  
    6. #define _Included_com_example_jniexample_JNIParamTest  
    7. #ifdef __cplusplus  
    8. extern "C" { 
    9. #endif  
    10. /* 
    11.  * Class:     com_example_jniexample_JNIParamTest 
    12.  * Method:    doTest 
    13.  * Signature: (Lcom/example/jniexample/JNIParam;)Lcom/example/jniexample/JNIParam; 
    14.  */ 
    15. JNIEXPORT jobject JNICALL Java_com_example_jniexample_JNIParamTest_doTest 
    16.   (JNIEnv *, jobject, jobject); 
    17.  
    18. #ifdef __cplusplus  
    19. #endif  
    20. #endif 

    b. c文件 (JNIParamTest.c)

    1. #include "JNIParamTest.h"  
    2.  
    3. #include "android/log.h"  
    4. #define TAG  "JNI_ParamTest"  
    5. #define LOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, TAG, fmt, ##args)  
    6.  
    7. /* 
    8.  * Class:     com_example_jniexample_JNIParamTest 
    9.  * Method:    doTest 
    10.  * Signature: (Lcom/example/jniexample/JNIParam;)Lcom/example/jniexample/JNIParam; 
    11.  */ 
    12. JNIEXPORT jobject JNICALL Java_com_example_jniexample_JNIParamTest_doTest 
    13.   (JNIEnv *env, jobject thiz, jobject paramIn) 
    14.     jclass paramInClass = (*env)->GetObjectClass(env, paramIn); 
    15.     if( paramInClass){ 
    16.         jboolean iscopy; 
    17.         jfieldID intId = (*env)->GetFieldID(env, paramInClass, "mInt", "I"); 
    18.         jint num = (int)(*env)->GetIntField(env, paramIn, intId); 
    19.         LOGD("num = %d", num); 
    20.  
    21.         jfieldID strId = (*env)->GetFieldID(env, paramInClass, "mString", "Ljava/lang/String;"); 
    22.         jstring str = (jstring)(*env)->GetObjectField(env, paramIn, strId); 
    23.         const char *locstr = (*env)->GetStringUTFChars(env, str, &iscopy); 
    24.         LOGD("str = %s", locstr); 
    25.  
    26.         (*env)->ReleaseStringUTFChars(env, str, locstr); 
    27.     } 
    28.  
    29.     jclass cls = (*env)->FindClass(env, "com/example/jniexample/JNIParam"); 
    30.     jmethodID id = (*env)->GetMethodID(env, cls, "<init>", "()V"); 
    31.  
    32.     jobject paramOut = (*env)->NewObjectA(env, cls, id, 0); 
    33.  
    34.     jfieldID  intId = (*env)->GetFieldID(env, cls, "mInt", "I"); 
    35.     (*env)->SetIntField(env, paramOut, intId, 1); 
    36.      
    37.     jfieldID  strId = (*env)->GetFieldID(env, cls, "mString", "Ljava/lang/String;"); 
    38.     (*env)->SetObjectField(env, paramOut, strId, (jstring)(*env)->NewStringUTF(env, "1")); 
    39.  
    40.     return paramOut; 

    四、提供一个测试环境

    1. package com.example.jniexample; 
    2.  
    3. import android.os.Bundle; 
    4. import android.app.Activity; 
    5. import android.view.Menu; 
    6.  
    7. public class JNIExample extends Activity { 
    8.  
    9.     @Override 
    10.     public void onCreate(Bundle savedInstanceState) { 
    11.         super.onCreate(savedInstanceState); 
    12.         setContentView(R.layout.activity_jniexample); 
    13.          
    14.         JNIParamTest test = new JNIParamTest(); 
    15.         test.runParamTest(); 
    16.     } 
    17.  
    18.     @Override 
    19.     public boolean onCreateOptionsMenu(Menu menu) { 
    20.         getMenuInflater().inflate(R.menu.activity_jniexample, menu); 
    21.         return true
    22.     } 

    实现了一个Activity, 启动就调用

    五、测试结果: (logcat 查看)

    1. D/JNIParamTest( 6135): print: mInt=0, mString=
    2. D/JNI_ParamTest( 6135): num = 
    3. D/JNI_ParamTest( 6135): str = 
    4. D/JNIParamTest( 6135): print: mInt=1, mString=
  • 相关阅读:
    [solr]
    [solr]
    [Linux] CentOS 加入开机启动
    [Linux] VirtualBox
    [Eclipse]
    [JBoss]
    [solr]
    [solr]
    [solr]
    [solr]
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/6155158.html
Copyright © 2011-2022 走看看