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. 洛谷——U10783 名字被和谐了

    https://www.luogu.org/problem/show?pid=U10783 题目背景 众所周知,我们称g是a的约数,当且仅当g是正数且a mod g = 0. 众所周知,若g既是a的约 ...

  2. STM32W108无线射频模块串行通信接口编程实例

    STM32W108无线射频模块UART通信应用实例 基于STM32W108芯片,编写串口測试程序,測试串口通信.完毕PC通过串口与STM32W108进行通信. 开发环境与硬件平台 硬件:STM32W1 ...

  3. 亚马逊AWS学习——EC2的自己定义VPC配置

    转载请注明出处:http://blog.csdn.net/dongdong9223/article/details/47153421 本文出自[我是干勾鱼的博客] 1 网络配置 EC2即亚马逊AWS云 ...

  4. 第一个使用Spring Tool Suite(STS)和Maven建立的Spring mvc 项目

    一.目标 在这篇文章中.我将要向您展示怎样使用Spring Frameworks 和 Maven build创建您的第一个J2ee 应用程序. 二.信息 Maven是一个java项目的构建工具(或者自 ...

  5. arukas 的 Endpoint

    arukas 的 Endpoint 什么是端点 What is Endpoint arukas.io 的实例几乎每周都自动重新启动,当实例重新启动时,其端口会更改.IP地址和端口的平均寿命是一周,有时 ...

  6. 利用 istio 来对运行在 Kubernetes 上的微服务进行管理

    尝试在一个准生产环境下,利用 istio 来对运行在 Kubernetes 上的微服务进行管理. 这一篇是第一篇,将一些主要的坑和环境准备工作. 内容较多,因此无法写成手把手教程,希望读者有一定 Ku ...

  7. JQuery滑动到指定位置

    $('html, body').animate({ scrollTop: next_tip.offset().top + "px"},500);

  8. 【“玲珑杯”ACM比赛 Round #20 H】康娜的数学课

    [链接]http://www.ifrog.cc/acm/problem/1161 [题意] 在这里写题意 [题解] 首先x<l肯定无解; 然后,肯定是要选其中的一些数字的. 而且这些数字肯定是大 ...

  9. 并发,one

    引言 最近工作当中写了一个有关并发的程序,引起了LZ对并发的强烈兴趣.这一下一发不可收拾,LZ用了一个多星期,看完了这本共280+页的并发编程书.之所以能看这么快,其实这主要归功于,自己之前对并发就有 ...

  10. Altium Designer的pcb界面如何让线变成点

    但是16版本,需要tools  ---  Grid Manager --双击 双击后: 转自:http://blog.csdn.net/ldcung/article/details/77411434