android jni 自定义对象为参数和返回值

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

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

package com.example.jniexample;

import android.util.Log;

public class JNIParam {
	public int mInt;
	public String mString;
	
	JNIParam(){
		mInt    = 0;
		mString = "0"; 
	}
	
	public void print(String tag){
		Log.d(tag, String.format("print: mInt=%d, mString=%s", mInt, mString));
	}
}

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

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

package com.example.jniexample;

public class JNIParamTest {
	private final String TAG = "JNIParamTest";
	
	static {
		System.loadLibrary("JNIParamTest");
	};

	public void runParamTest(){
		JNIParam paramIn = new JNIParam();
		paramIn.print(TAG);
		
		JNIParam paramOut = doTest(paramIn);
		if( paramOut != null ) paramOut.print(TAG);
	}
	
	//JNI
	private native JNIParam doTest(JNIParam paramIn);
}

三、实现JNI的本地实现

a. 头文件 (JNIParamTest.h)

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

#ifndef _Included_com_example_jniexample_JNIParamTest
#define _Included_com_example_jniexample_JNIParamTest
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_example_jniexample_JNIParamTest
 * Method:    doTest
 * Signature: (Lcom/example/jniexample/JNIParam;)Lcom/example/jniexample/JNIParam;
 */
JNIEXPORT jobject JNICALL Java_com_example_jniexample_JNIParamTest_doTest
  (JNIEnv *, jobject, jobject);

#ifdef __cplusplus
}
#endif
#endif

b. c文件 (JNIParamTest.c)

#include "JNIParamTest.h"

#include "android/log.h"
#define TAG  "JNI_ParamTest"
#define LOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, TAG, fmt, ##args)

/*
 * Class:     com_example_jniexample_JNIParamTest
 * Method:    doTest
 * Signature: (Lcom/example/jniexample/JNIParam;)Lcom/example/jniexample/JNIParam;
 */
JNIEXPORT jobject JNICALL Java_com_example_jniexample_JNIParamTest_doTest
  (JNIEnv *env, jobject thiz, jobject paramIn)
{
    jclass paramInClass = (*env)->GetObjectClass(env, paramIn);
    if( paramInClass){
        jboolean iscopy;
        jfieldID intId = (*env)->GetFieldID(env, paramInClass, "mInt", "I");
        jint num = (int)(*env)->GetIntField(env, paramIn, intId);
        LOGD("num = %d", num);

        jfieldID strId = (*env)->GetFieldID(env, paramInClass, "mString", "Ljava/lang/String;");
        jstring str = (jstring)(*env)->GetObjectField(env, paramIn, strId);
        const char *locstr = (*env)->GetStringUTFChars(env, str, &iscopy);
        LOGD("str = %s", locstr);

        (*env)->ReleaseStringUTFChars(env, str, locstr);
    }

    jclass cls = (*env)->FindClass(env, "com/example/jniexample/JNIParam");
    jmethodID id = (*env)->GetMethodID(env, cls, "<init>", "()V");

    jobject paramOut = (*env)->NewObjectA(env, cls, id, 0);

    jfieldID  intId = (*env)->GetFieldID(env, cls, "mInt", "I");
    (*env)->SetIntField(env, paramOut, intId, 1);
    
    jfieldID  strId = (*env)->GetFieldID(env, cls, "mString", "Ljava/lang/String;");
    (*env)->SetObjectField(env, paramOut, strId, (jstring)(*env)->NewStringUTF(env, "1"));

    return paramOut;
}


四、提供一个测试环境

package com.example.jniexample;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;

public class JNIExample extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_jniexample);
        
        JNIParamTest test = new JNIParamTest();
        test.runParamTest();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_jniexample, menu);
        return true;
    }
}

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


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

D/JNIParamTest( 6135): print: mInt=0, mString=0
D/JNI_ParamTest( 6135): num = 0
D/JNI_ParamTest( 6135): str = 0
D/JNIParamTest( 6135): print: mInt=1, mString=1


六、其他类型转换可以参考:

http://blog.csdn.net/henry121212/article/details/7482527   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值