继上一篇,我们在native接口中编写了2个方法
生成的相应.h文件
这时,需要我们自己去完善.c文件
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
#include <android/log.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h> /* Header for class led_oki_com_jnidemo_AppJNI */ #ifndef _Included_led_oki_com_jnidemo_AppJNI
#define _Included_led_oki_com_jnidemo_AppJNI
#ifdef __cplusplus
extern "C" {
#endif 这段可不变,固定
#include "android/log.h"
#define TAG "jnidemo-jni-test" // 这个是自定义的LOG的标识
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,TAG,__VA_ARGS__) // 定义LOGD类型 这段主要是自定义的LOG标识,相当于Android中的LOG.D()方法 方法一:getStringFromNative
JNIEXPORT jstring JNICALL Java_com_oki_led_jni_AppJNI_getStringFromNative
(JNIEnv * env, jobject jObj){
LOGD("log string from ndk.");
return env->NewStringUTF(env,"Hello From JNI!");
} 这段,对应我们的native写的方法之一getStringFromNative,自定义的LOG使用则是使用自定义的方法名LOGD("提示内容")
这个方法意思是返回一个String类型的数据,数据是Hello From JNI!
在Android里就可以接收到这段String
AppJNI appJNI = new AppJNI();
String msg = appJNI.getStringFromNative();
这时,msg接收的数据就是Hello From JNI! 方法二:doCoordTest(COORD coord)
JNIEXPORT jobject JNICALL Java_com_oki_led_jni_AppJNI_doCoordTest
(JNIEnv *env, jobject obj, jobject coord) {
jclass coordClass = (*env)->GetObjectClass(env, coord);
if( coordClass){
jboolean iscopy;
jfieldID xId = (*env)->GetFieldID(env, coordClass, "x", "I");
jint x = (int)(*env)->GetIntField(env, coord, xId);
LOGD("x = %d", x); jfieldID yId = (*env)->GetFieldID(env, coordClass, "y", "I");
jint y = (int)(*env)->GetIntField(env, coord, yId);
LOGD("y = %d", y); jfieldID widthId = (*env)->GetFieldID(env, coordClass, "width", "I");
jint width = (int)(*env)->GetIntField(env, coord, widthId);
LOGD("width = %d", width); jfieldID heightId = (*env)->GetFieldID(env, coordClass, "height", "I");
jint height = (int)(*env)->GetIntField(env, coord, heightId);
LOGD("height = %d", height);
} jclass cls = (*env)->FindClass(env, "com/oki/led/jni/nativeobj/COORD");
jmethodID id = (*env)->GetMethodID(env, cls, "<init>", "()V"); jobject paramOut = (*env)->NewObjectA(env, cls, id, 0); return paramOut;
} 其中,COORD是在Android中创建的一个COORD对象类
public class COORD {
public int x;
public int y;
public int width;
public int height; /**
* 设置初始值
* 为什么要设置初始值:防止在执行c文件中,数据出错或内容溢出等不必要的问题,也减少在c文件中对数据的判断,懒人方法(可用可不用)
*/
public COORD() {
x = 0;
y = 0;
width = 0;
height = 0;
}
}
如果native中设置的传递一个类,那么c文件中,一开始接收的数据应该是jobject类型,通过jobject类型转换成jclass类型,再取出class类中各个数值 jclass coordClass = (*env)->GetObjectClass(env, coord); 片段1:取值 //取类中的数值 x ID
jfieldID xId = (*env)->GetFieldID(env, coordClass, "x", "I");
//将 x ID 转换成相应类型的 x 数值
jint x = (int)(*env)->GetIntField(env, coord, xId);
//打印 x 数据,用于在Android运行过程中,判断该数值是否正确
LOGD("x = %d", x); 片段2:调用初始方法 //查找class 类 COORD
jclass cls = (*env)->FindClass(env, "com/oki/led/jni/nativeobj/COORD");
//对该类调用其初始化方法
jmethodID id = (*env)->GetMethodID(env, cls, "<init>", "()V");
//将cls类中的数据再转成jobject类
jobject paramOut = (*env)->NewObjectA(env, cls, id, 0);
//将数据返回出去
return paramOut; 片段3:赋值 如果需要将片段1中的取值内容返回出去,需要再新创建一个jobject方法承载这些数据
//查找class 类 COORD
jclass cls = (*env)->FindClass(env, "com/oki/led/jni/nativeobj/COORD");
//可要可不要
jmethodID id = (*env)->GetMethodID(env, cls, "<init>", "()V");
//将cls类中的数据再转成jobject类
jobject paramOut = (*env)->NewObjectA(env, cls, id, 0); jfieldID xId = (*env)->GetFieldID(env, coordClass, "x", "I");
//将xId赋值为3
(*env)->SetIntField(env, paramOut, xId, 3); return paramOut; 基本上就是这样,遗留问题:赋值是否有更方便的方法?里面是否有一些代码重复?
Android Studio中JNI -- 2 -- 编写c文件的更多相关文章
-
Android studio中找不到so文件的问题:java.lang.UnsatisfiedLinkError
解决Android studio中找不到so文件的问题:java.lang.UnsatisfiedLinkError 表示我们不编译jni代码,直接从libs里面复制so库 文件路径:app\buil ...
-
Android Studio中JNI程序的单步调试和日志打印
近日有个算法(检测碰撞)需要用C++实现,目的是IOS和ANDROID*享同一段程序. 下面说说android调用这段程序过程中遇到的一些事情.(过程中网上搜索了一些相关文章,大部分说的是eclip ...
-
android studio 中jni底层日志的打印
1 添加ndk对log支持若需要添加ndk对log的支持,只需要通过以下2步即可实现. 1.1 修改Android.mk如生成的库文件是“.so文件”,则在Android.mk中添加如下内容:LOCA ...
-
Android Studio中JNI -- 1 -- 配置方法
1.配置NDK 1.1 下载NDK Android Studio 1.2 配 android-ndk-r10e,不同版本的Studio需要配置不同的ndk,下载完成后,随便解压放至某个文件目录下 1. ...
-
Android Studio中新建和引用assets文件
从eclipse转过的朋友们应该不太习惯AS中新建assets文件和对文件内容的引用.我也查找了网上很多资料发现很少有这样的解决答案,于是便把自己解决的方法总结在这里. 1.一般新建project后这 ...
-
Android studio中2种build.gradle文件介绍
根目录下的build.gradle通常不需要修改这个文件中的内容,除非需要添加一些全局的项目构建配置 buildscript { repositories { google() //声明代码托管仓库G ...
-
如何在Android Studio中创建jniLib和asset文件夹 2
1.创建asset文件夹 如图进行操作 2.创建jniLib文件夹 —打开app下面的gradle文件(不是project的gradle) —在gradle文件的Android标签里面添加 sourc ...
-
Android studio 中创建AIDL Service
1.概述 AIDL在android系统中的作用 AIDL,Android Interface definition language的缩写,它是一种android内部进程通信接口的描写叙述语言, ...
-
android studio 使用 jni 编译 opencv 完整实例 之 图像边缘检测!从此在andrid中*使用 图像匹配、识别、检测
目录: 1,过程感慨: 2,运行环境: 3,准备工作: 4,编译 .so 5,遇到的关键问题及其解决方法 6,实现效果截图. (原创:转载声明出处:http://www.cnblogs.com/lin ...
随机推荐
-
Mac OS 中的 Python(和 NumPy)开发环境设置
http://www.python()tab.com/html/2013/pythonjichu_1010/582.html ()需要删除
-
C#的lock关键字
using System; using System.Threading; namespace Test { class Program { //一.Lock定义 //lock 关键字可以用来确保代码 ...
-
Android学习4&mdash;短信发送器的实现
界面预览: 由图中可以看出,此APP需要的组件有:两个TextView,一个用于显示手机号码的标题,另一个用于显示短信内容的标题. ...
-
selenium+eclipse+python环境
1.下载并安装jdk,配置环境变量: 2.下载并安装python,配置path系统环境变量:D:\Program Files\python34: 3.安装selenium,在安装好的python路径D ...
-
eclipse背景主题
长时间对着电脑敲代码,眼睛受不了啊,果然程序员就没*吗?之前咱给codeblocks背景换了颜色,去官网上粘粘代码然后替换一下就行了,这里不多说, 这里说的是给ecllipse换主题,按理说ecli ...
-
unknown filesystem type ‘iso9660’类型问题--Ubuntu
unknown filesystem type ‘iso9660’是指系统不支持这种类型的文件, 用以下命令更新内核即可: sudo aptitude update sudo aptitude upg ...
-
CSS根据子元素个数不同定义样式
近日面试,遇见了一个这样的问题,不会,便记下来. 问题:如何根据子元素个数的不同定义不同的样式? 代码:HTML <ul> <li>1</li> <li> ...
-
Android开发艺术探索——第二章:IPC机制(上)
Android开发艺术探索--第二章:IPC机制(上) 本章主要讲解Android的IPC机制,首先介绍Android中的多进程概念以及多进程开发模式中常见的注意事项,接着介绍Android中的序列化 ...
-
MySQL之爱之初体验
写在前言:本篇博客从mysql的安装开始说起,至于什么是数据库以及数据的由来什么的,不在详谈!!! 第一:mysql安装 linux安装:两种方式 1.apt安装 apt install mysql- ...
-
String字符串的常用方法
1.substr():可在字符串中抽取从 start 下标开始的指定数目的字符. stringObject.substr(start,length) start:必需.要抽取的子串的起始下标.必须是数 ...