Android Studio中JNI -- 2 -- 编写c文件

继上一篇,我们在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 __cplusplusextern "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里就可以接收到这段StringAppJNI 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 IDjfieldID 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 类 COORDjclass 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 类 COORDjclass 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;

基本上就是这样,遗留问题:赋值是否有更方便的方法?里面是否有一些代码重复?
时间: 2024-12-10 09:21:04

Android Studio中JNI -- 2 -- 编写c文件的相关文章

android studio 中jni底层日志的打印

1 添加ndk对log支持若需要添加ndk对log的支持,只需要通过以下2步即可实现. 1.1 修改Android.mk如生成的库文件是".so文件",则在Android.mk中添加如下内容:LOCAL_LDLIBS:=-L$(SYSROOT)/usr/lib -llog如生成的库文件是".a文件",则在Android.mk中添加如下内容:LOCAL_LDLIBS:=-llog 1.2 在.c或.cpp文件中引用log头文件添加如下内容:// 引入log头文件#in

Android Studio中JNI -- 1 -- 配置方法

1.配置NDK 1.1 下载NDK Android Studio 1.2 配 android-ndk-r10e,不同版本的Studio需要配置不同的ndk,下载完成后,随便解压放至某个文件目录下 1.2 指定NDK目录 1.3 修改build.gradle配置 需要修改的是在<Project>\app\build.gradle 2. 添加native接口 2.1 添加native 2.2 执行build -> Make Project 确定程序无错误,并生成.class文件 2.3 通过

在android studio中,使用getAssets获取文件的问题

今天写了一个拷贝数据库的函数,但是怎么都在文件夹下看不到数据库,后来发现是获取不到资源文件, 在Android studio下, assets文件夹应该放在跟java和res同级目录下 版权声明:本文为博主原创文章,未经博主允许不得转载.

Android studio中2种build.gradle文件介绍

根目录下的build.gradle通常不需要修改这个文件中的内容,除非需要添加一些全局的项目构建配置 buildscript { repositories { google() //声明代码托管仓库Google jcenter() //声明代码托管仓库,用于引用jcenter上的开源项目 } dependencies { classpath 'com.android.tools.build:gradle:3.1.0' //声明了一个Gradle插件用来作为Android开发.3.1.0为grad

Android如何使用so文件和Android studio中导入so

Android中使用so文件: 做一个PDF阅读的功能,找到一个开源的库,mupdf.下载的是网上编译好的so库,导入到自己项目中的时候一直报错Java.lang.UnsatisfiedLinkError: Couldn't load netplayerlibq: findLibrary returned null,找不到so文件中的方法.找了一个下午,终于知道了原因. JNI中的方法的命名规范是 1) 前缀: Java_2) 类的全限定名,用下划线进行分隔(_):com_lms_jni_Jni

Android studio中正确引入so文件的方法

相信很多朋友在使用Android studio开发中,遇到过如何引入第三方so文件的问题,然而第三方官方仅仅给出了ADT环境下的集成方式. Android studio中默认使用的是gradle编译方式,与ADT编辑方式不一样,那么so文件应当如何引入呢? 其实很简单.这里以集成JPUSH为例,看一下so文件如何引入到编译环境,最终到JNI直接可以调用该so文件. 首先,在我们的Module的根目录中建立libs目录,将jpush集成SDK中的so文件分别拷入,截图如下: apply plugi

android studio 使用 jni 编译 opencv 完整实例 之 图像边缘检测!从此在andrid中自由使用 图像匹配、识别、检测

目录: 1,过程感慨: 2,运行环境: 3,准备工作: 4,编译 .so 5,遇到的关键问题及其解决方法 6,实现效果截图. ------------------------------------------------------------------------ (原创:转载声明出处:http://www.cnblogs.com/linguanh/) 1,过程感慨(想直接看教程,请跳过此部分) 在写具体内容之前,我先说下我搞这个东西的过程,由于导师之前说过要搞个图像匹配的androi A

Android Studio中清单文件改versionCode和versionName没效果的原因

在Android Studio中,项目的versionCode 和versionName 的控制不是在AndroidManifest.xml清单文件中更改的,而是在项目的build.gradle中更改的,. 其实在AndroidManifest.xml里已经有提示了的: 然后在build.gradle中会发现相同的声明: 修改后同步一下就行了.

Android Studio中如何自定义文件类头?

在android studio开发工具的使用中,如果我们能掌握一些小技巧,那我们的开发工作往往能事半功倍,今天给大家介绍一个很简单的"小"技巧. 平时, 我们在Android Studio中开发Android时, 总免不了要创建新的文件, 也许是Java文件, 也许是C和C++文件. 不过, Android Studio每次给我们生成的Java类都会包含一个头部的注释, 例如: /**  * Created by enmingx on 14/09/16.  */ 这样虽然还不错, 但是