Android JNI 自定义对象为参数和返回值
ndroid 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
Android JNI 自定义对象为参数和返回值的更多相关文章
- Android开发 AIDL使用自定义对象作参数或返回值
http://www.pocketdigi.com/20121129/952.html 默认,AIDL支持对象作参数,但需要该对象实现Parcelable接口,且aidl文件应该是该类在同一包下,需要 ...
- STL算法设计理念 - 函数对象和函数对象当参数和返回值
函数对象: 重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象.一个类对象,表现出一个函数的特征,就是通过"对象名+(参数列表)&qu ...
- Android调用远程Service的参数和返回值都需要实现Parcelable接口
import android.os.Parcel;import android.os.Parcelable; public class Person implements Parcelable{ pr ...
- Python rich comparisons 自定义对象比较过程和返回值
Classes wishing to support the rich comparison mechanisms must add one or more of the following new ...
- 论DATASNAP远程方法支持自定义对象作参数
论DATASNAP远程方法支持自定义对象作参数 DATASNAP远程方法已经可以支持自定义对象作参数,这是非常方便的功能. 1)自定义对象 type TMyInfo = class(TObject) ...
- 匿名对象作为方法的参数和返回值与Random概念和基本使用
应用场景 1. 创建匿名对象直接调用方法,没有变量名. new Scanner(System.in).nextInt(); 2. 一旦调用两次方法,就是创建了两个对象,造成浪费,请看如下代码. new ...
- day09-Python运维开发基础(函数收集参数、命名关键字参数与返回值、函数名的特殊使用及 全局/局部变量详解)
1. 函数收集参数.命名关键字参数与返回值.函数名的特殊使用 # ### 默认形参 和 关键字实参 # 默认形参和 关键字实参 在写法上是一样 # 函数的定义处 """默 ...
- SpringMVC源码学习:容器初始化+MVC初始化+请求分发处理+参数解析+返回值解析+视图解析
目录 一.前言 二.初始化 1. 容器初始化 根容器查找的方法 容器创建的方法 加载配置文件信息 2. MVC的初始化 文件上传解析器 区域信息解析器 handler映射信息解析 3. Handler ...
- 速战速决 (3) - PHP: 函数基础, 函数参数, 函数返回值, 可变函数, 匿名函数, 闭包函数, 回调函数
[源码下载] 速战速决 (3) - PHP: 函数基础, 函数参数, 函数返回值, 可变函数, 匿名函数, 闭包函数, 回调函数 作者:webabcd 介绍速战速决 之 PHP 函数基础 函数参数 函 ...
随机推荐
- 洛谷P1622 释放囚犯
题目描述 Caima王国中有一个奇怪的监狱,这个监狱一共有P个牢房,这些牢房一字排开,第i个紧挨着第i+1个(最后一个除外).现在正好牢房是满的. 上级下发了一个释放名单,要求每天释放名单上的一个人. ...
- Flask项目之手机端租房网站功能测试(完结)
说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 目录 一丶注册和登录以及用户退出功能 二丶上传头像功能和修改用户名功能测试 三丶发布房源以及实名认证功能测试 四丶网站房屋搜索功能 ...
- Debian9 安装后的配置笔记
安装Debian9后,需要做的事,具体如下: 以下内容主要参考:https://www.cnblogs.com/OneFri/p/8308340.html感谢作者的分享. su 输入密码,登录root ...
- APM2.8 Rover 自己主动巡航车设计(固件安装和设置)
1.2 APM2.8软件安装与固件下载 下载Mission Planner这个地面基站软件,这里介绍的是windoews平台下的,在MAC或者linux下能够使用QGroundCont基于QT编写的地 ...
- matlab 辅助函数 —— 文件下载与文件解压
0. 可读性的提升 为了提升代码的交互友好性,可在代码执行一些耗时操作时,显示地输出一些文本信息,以显示进度: fprintf('Downloading xxfilename...\n') urlwr ...
- 设置Maven默认的JDK为1.7,解决Update Maven Project默认为1.5和Maven打包报错2个问题
1.之前,一直遇到这个问题. Update Maven Project的时候,JDK变成了1.5的. 如果项目中有使用"@overdide",程序就会报错,需要手动修改JRE ...
- 原生js大总结四
031.数组常用的一些方法 1.push: 在数组最后添加一个或者多个元素,返回添加后数组的长度 2.pop: 从数组最后取出一个元素,返回的是数组的最后一个元素(取出的元素) 3.uns ...
- 在设置了android:parentActivityName后,点击子Activity返回键,父Activity总会调用OnDestroy()的解决方式
近期查了非常久这个事情.分享给大家, 原理非常easy,一个Activity在manifet里声明了android:parentActivityName:这时候通过Activity左上角的返回butt ...
- 谈谈vector容器的三种遍历方法
说明:本文仅供学习交流.转载请标明出处.欢迎转载! vector容器是最简单的顺序容器,其用法相似于数组.实际上vector的底层实现就是採用动态数组.在编敲代码的过程中.经常会变量 ...
- Redis源代码分析(八)--- t_hash哈希转换
在上次的zipmap分析完之后,事实上关于redis源码结构体部分的内容事实上已经所有结束了.由于以下还有几个和结构体相关的操作类,就页把他们归并到struct包下了.这类的文件有:t_hash.c, ...