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. 2.1 Producer API官网剖析(博主推荐)

    不多说,直接上干货! 一切来源于官网 http://kafka.apache.org/documentation/ 2.1 Producer API 2.1.生产者API 我们鼓励所有新开发的程序使用 ...

  2. 用硬件卡克隆Linux集群

    650) this.width=650;" onclick="window.open("http://blog.51cto.com/viewpic.php?refimg= ...

  3. JavaScript--Module模式

    //module: Module模式是JavaScript编程中一个非常通用的模式 window.onload = function() { //1.基本使用: var MyFn = function ...

  4. session应用二

    从session中获取mapper对象,利用mapper对象进行增删改查 Date now = new Date(); SqlSession session = this.yangchebaoDbMa ...

  5. 洛谷 P1014 Cantor表

    P1014 Cantor表 题目描述 现代数学的著名证明之一是Georg Cantor证明了有理数是可枚举的.他是用下面这一张表来证明这一命题的: 1/1 1/2 1/3 1/4 1/5 … 2/1 ...

  6. 需求:在浏览器加载完毕后,自动播放视频:出现play() failed because the user didn't interact with the document first.错误

    解决方法:给video标签加入<video muted></video> 静音即可. Chrome 66为了避免标签产生随机噪音. 参考链接:https://juejin.im ...

  7. v-for一定要与v-bind:key="id"连用

    1. v-for: <div v-for="(item,index) in todolist" v-bind:key="item.id"> < ...

  8. PatentTips - Adaptive algorithm for selecting a virtualization algorithm in virtual machine environments

    BACKGROUND A Virtual Machine (VM) is an efficient, isolated duplicate of a real computer system. Mor ...

  9. jmeter--元件的作用域与执行顺序

    1.元件的作用域 JMeter中共有8类可被执行的元件(测试计划与线程组不属于元件),这些元件中,取样器是典型的不与其它元件发生交互作用的元件,逻辑控制器只对其子节点的取样器有效,而其它元件(conf ...

  10. [WPF自定义控件库]使用TextBlockHighlightSource强化高亮的功能,以及使用TypeConverter简化调用

    1. 强化高亮的功能 上一篇文章介绍了使用附加属性实现TextBlock的高亮功能,但也留下了问题:不能定义高亮(或者低亮)的颜色.为了解决这个问题,我创建了TextBlockHighlightSou ...