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

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

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

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

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

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

三、实现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. #ifndef _Included_com_example_jniexample_JNIParamTest
  5. #define _Included_com_example_jniexample_JNIParamTest
  6. #ifdef __cplusplus
  7. extern "C" {
  8. #endif
  9. /*
  10. * Class:     com_example_jniexample_JNIParamTest
  11. * Method:    doTest
  12. * Signature: (Lcom/example/jniexample/JNIParam;)Lcom/example/jniexample/JNIParam;
  13. */
  14. JNIEXPORT jobject JNICALL Java_com_example_jniexample_JNIParamTest_doTest
  15. (JNIEnv *, jobject, jobject);
  16. #ifdef __cplusplus
  17. }
  18. #endif
  19. #endif

b. c文件 (JNIParamTest.c)

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

四、提供一个测试环境

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

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

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

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

Android JNI 自定义对象为参数和返回值的更多相关文章

  1. Android开发 AIDL使用自定义对象作参数或返回值

    http://www.pocketdigi.com/20121129/952.html 默认,AIDL支持对象作参数,但需要该对象实现Parcelable接口,且aidl文件应该是该类在同一包下,需要 ...

  2. STL算法设计理念 - 函数对象和函数对象当参数和返回值

    函数对象: 重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象.一个类对象,表现出一个函数的特征,就是通过"对象名+(参数列表)&qu ...

  3. Android调用远程Service的参数和返回值都需要实现Parcelable接口

    import android.os.Parcel;import android.os.Parcelable; public class Person implements Parcelable{ pr ...

  4. Python rich comparisons 自定义对象比较过程和返回值

    Classes wishing to support the rich comparison mechanisms must add one or more of the following new ...

  5. 论DATASNAP远程方法支持自定义对象作参数

    论DATASNAP远程方法支持自定义对象作参数 DATASNAP远程方法已经可以支持自定义对象作参数,这是非常方便的功能. 1)自定义对象 type TMyInfo = class(TObject) ...

  6. 匿名对象作为方法的参数和返回值与Random概念和基本使用

    应用场景 1. 创建匿名对象直接调用方法,没有变量名. new Scanner(System.in).nextInt(); 2. 一旦调用两次方法,就是创建了两个对象,造成浪费,请看如下代码. new ...

  7. day09-Python运维开发基础(函数收集参数、命名关键字参数与返回值、函数名的特殊使用及 全局/局部变量详解)

    1. 函数收集参数.命名关键字参数与返回值.函数名的特殊使用 # ### 默认形参 和 关键字实参 # 默认形参和 关键字实参 在写法上是一样 # 函数的定义处 """默 ...

  8. SpringMVC源码学习:容器初始化+MVC初始化+请求分发处理+参数解析+返回值解析+视图解析

    目录 一.前言 二.初始化 1. 容器初始化 根容器查找的方法 容器创建的方法 加载配置文件信息 2. MVC的初始化 文件上传解析器 区域信息解析器 handler映射信息解析 3. Handler ...

  9. 速战速决 (3) - PHP: 函数基础, 函数参数, 函数返回值, 可变函数, 匿名函数, 闭包函数, 回调函数

    [源码下载] 速战速决 (3) - PHP: 函数基础, 函数参数, 函数返回值, 可变函数, 匿名函数, 闭包函数, 回调函数 作者:webabcd 介绍速战速决 之 PHP 函数基础 函数参数 函 ...

随机推荐

  1. Ajax : $. get()和$.post() $.getScript $.getJSON

    <body> <input type="button" value="Ajax" /> <div id="box&quo ...

  2. STL中erase()的陷阱

    最近在刷stl源码剖析这本书时,对于vector的erase()函数引起了我的注意 在删除单个元素时是这样定义的: iterator erase(iterator position){ !=end() ...

  3. IOS开发UI基础--数据刷新

    IOS开发UI基础--数据刷新 cell的数据刷新包括下面几个方面 加入数据 删除数据 更改数据 全局刷新方法(最经常使用) [self.tableView reloadData]; // 屏幕上的全 ...

  4. zico源代码分析(二) 数据读取和解析部分

    第一部分:分析篇 首先,看一下zico的页面,左侧是hostname panel,右侧是该主机对应的traces panel. 点击左侧zorka主机名,右侧panel会更新信息,在火狐浏览器中使用f ...

  5. Python 极简教程(八)字符串 str

    由于字符串过于重要,请认真看完并保证所有代码都至少敲过一遍. 对于字符串,前面在数据类型中已经提到过.但是由于字符串类型太过于常用,Python 中提供了非常多的关于字符串的操作.而我们在实际编码过程 ...

  6. ArcGIS 10.5 新功能

    ArcGIS 10.5正式发布,打造智能的Web GIS平台 2017年新年来临之际,ArcGIS 10.5正式发布. 历经几个版本,ArcGIS10.5已经革新为一个智能的以Web为中心的地理平台, ...

  7. Altium Designer如何统一调整标号大小,在pcb环境下

  8. PythonOOP面向对象编程3

    override 函数重写 重写是在自定义的类内添加相应的方法,让自定义的类生成的对象(实例)像内建对象一样进行内建的函数操作 对象转字符串函数重写 repr(obj) 返回一个能代表此对象的表达式字 ...

  9. Loadrunner--负载生成器

    对场景进行设计后,接着需要对负载生成器进行管理和设置.Load Generator是运行脚本的负载引擎,在默认情况下使用本地的负载生成器来运行脚本,但是模拟用户行为也需要消耗一定的系统资源,所以在一台 ...

  10. NodeJS服务端重构计划

    不知不觉做node开发已经半年时间了.这期间写尝试着去攻克了一些问题.实现了一下想法,也遇到过一些坑. 是时候来梳理一下代码,规划一下接下来的工作. 现阶段我们的nodeserver端代码结构是这种: ...