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. 关于大数据项目创建时所需setting.xml(博主推荐)

    我目前,收录经常用的是,这两个版本,这个根据博主我本人的经验之谈,最为稳定和合理的. 注意:我的本地路径是在D:/SoftWare/maven/repository,大家自己改为你们自己的即可.   ...

  2. 洛谷P2660 zzc 种田

    题目背景 可能以后 zzc就去种田了. 题目描述 田地是一个巨大的矩形,然而zzc 每次只能种一个正方形,而每种一个正方形时zzc所花的体力值是正方形的周长,种过的田不可以再种,zzc很懒还要节约体力 ...

  3. Red Hat Enterprise Linux Server 5.5新增功能简介

    一.概况 昨日对刚发布的redhat新产品RHEL5.5进行了小范围的测试,红帽企业版 Linux 5.5 发行本中的亮点包括针对 Intel Boxboro-EX 平台.AMD Magny-Cour ...

  4. js全选反选按钮实现

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  5. Java调用jama实现矩阵运算

    Java调用jama实现矩阵运算 一.jama简介 Jama是一个基本的线性代数java包.包括一个基本的Matrix类和5个矩阵分解类. Matrix类提供了基本的线性代数数值运算的功能,不同的构造 ...

  6. 洛谷—— P1190 接水问题

    https://www.luogu.org/problem/show?pid=1190#sub 题目描述 学校里有一个水房,水房里一共装有 m 个龙头可供同学们打开水,每个龙头每秒钟的 供水量相等,均 ...

  7. ASP.NET MVC案例教程(基于ASP.NET MVC beta)——第六篇:拦截器

    摘要      本文将对“MVC公告发布系统”的发布公告功能添加日志功能和异常处理功能,借此来讨论ASP.NET MVC中拦截器的使用方法. 一个小难题      我们继续完善“MVC公告发布系统”, ...

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

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

  9. Java Web学习总结(18)——JSP标签

    一.JSP标签介绍 JSP标签也称之为Jsp Action(JSP动作)元素,它用于在Jsp页面中提供业务逻辑功能,避免在JSP页面中直接编写java代码,造成jsp页面难以维护. 二.JSP常用标签 ...

  10. Mrakdonw学习

    转载请注明出处:http://blog.csdn.net/cym492224103 什么是Mrakdown 为什么使用Mrakdown 怎样Mrakdown 字体 删除线 字体大小 引用 代码行代码块 ...