Android NDK开发(二)——JNIEnv、jobject与jclass关系

本文主要讲解Android NDK开发中JNIEnv、jobject与jclass的相关知识,并用c和c++两种语言实现了jobject和jclass。


本专栏知识点是通过<零声教育>的音视频流媒体高级开发课程进行系统学习,梳理总结后写下文章,对音视频相关内容感兴趣的读者,可以点击观看课程网址:零声教育


Android NDK开发(二)——JNIEnv、jobject与jclass关系

JNIEnv、jobject与jclass关系

JavaVM 和 Env 的关系

  1. JavaVm是虚拟机在jni层的代表,⼀个进程只有⼀个JavaVm,所有线程共⽤⼀个JavaVM。
  2. JNIEnv 是⼀个线程相关的结构体,它代表了java的运⾏环境 。每⼀个线程都会有⼀个,不同的线程中
    不能相互调⽤,每个JNIEnv都是线程专有的。 jni中可以拥有很多个JNIEnv,可以使⽤它来进⾏java层
    和native层的调⽤。
  3. JNIEnv 是⼀个指针,指向⼀个线程相关的结构,线程相关结构指向了JNI函数指针数组。这个数组⾥⾯
    定义了⼤量的JNI函数指针。
  4. 在同⼀个线程中,多次调⽤JNI层⽅法,传⼊的JNIEnv都是相同的。
  5. 在java层定义的本地⽅法,可以在不同的线程中调⽤,因此是可以接受不同的JNIEnv。

jobject和jclass区别:
jobject:实例引⽤(C++的说法:对象引⽤)(普通函数)
jclass: 类引⽤ (静态函数)

jobject和jclass实现

创建一个新项目,
java->com.example.ndk4_3->MainActivity文件中,添加声明

static public native String staticstringFromJNI();

在这里插入图片描述
之后利用java.h自动生成JNI接口
在这里插入图片描述
自动生成接口:
在这里插入图片描述
修改cpp->native-lib.cpp

extern "C" JNIEXPORT jstring JNICALL
Java_com_example_ndk4_13_MainActivity_staticstringFromJNI
        (JNIEnv *env,
                jclass){
    std::string hello = "Static Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

此时调用的,普通函数就是jobject,静态函数就是jclass,与c++中类似,静态函数是属于整个类的,而普通函数属于每个对象的。
在这里插入图片描述
之后,修改对应文件,运行程序。
修改res->layout->activity_main.xml文件,设置布局

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/sample_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="50dp"
        android:text="Hello World!"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/sample_text2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="100dp"
        android:text="Hello World!"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

布局预览如下:
在这里插入图片描述
修改java->com.example.ndk4_3->MainActivity文件

	TextView tv2 = findViewById(R.id.sample_text2);
	tv2.setText(staticstringFromJNI());

在这里插入图片描述
之后运行即可:
在这里插入图片描述

利用c语言实现

cpp->includes->CMaketList.txt中的native-lib.cpp修改为native-lib.c
在这里插入图片描述
新建一个native-lib.c如下

#include <jni.h>

JNIEXPORT jstring JNICALL
Java_com_example_ndk4_13_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject obj/* this */) {
    char str[] = "Hello from C";
    return (*env)->NewStringUTF(env, str);
}
JNIEXPORT jstring JNICALL
Java_com_example_ndk4_13_MainActivity_staticstringFromJNI
        (JNIEnv *env,
                jclass jcs){
    char str[] = "Static Hello from C";
    return (*env)->NewStringUTF(env, str);
}

运行:
在这里插入图片描述

  • 27
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在使用 Android NDK Camera 开发时,可以通过调用 Camera.Parameters 的 setExposureCompensation(int) 方法来关闭曝光控制。具体实现代码如下: ``` #include <android/native_window_jni.h> #include <android/native_window.h> #include <android/log.h> #include <android/bitmap.h> #include <jni.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <time.h> #include <math.h> #include <pthread.h> #include <unistd.h> #include <fcntl.h> #include <sys/mman.h> #include <sys/ioctl.h> #include <linux/videodev2.h> #define LOG_TAG "NDKCamera" #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) extern "C" { JNIEXPORT void JNICALL Java_com_example_ndkcamera_CameraActivity_setExposureCompensation(JNIEnv* env, jobject obj, jint value); }; void Java_com_example_ndkcamera_CameraActivity_setExposureCompensation(JNIEnv* env, jobject obj, jint value) { jclass cameraClass = env->FindClass("android/hardware/Camera"); jmethodID openMethodID = env->GetStaticMethodID(cameraClass, "open", "(I)Landroid/hardware/Camera;"); jobject cameraObject = env->CallStaticObjectMethod(cameraClass, openMethodID, 0); jmethodID getParametersMethodID = env->GetMethodID(cameraClass, "getParameters", "()Landroid/hardware/Camera$Parameters;"); jobject parametersObject = env->CallObjectMethod(cameraObject, getParametersMethodID); jclass parametersClass = env->FindClass("android/hardware/Camera$Parameters"); jmethodID setExposureCompensationMethodID = env->GetMethodID(parametersClass, "setExposureCompensation", "(I)V"); env->CallVoidMethod(parametersObject, setExposureCompensationMethodID, value); jmethodID setParametersMethodID = env->GetMethodID(cameraClass, "setParameters", "(Landroid/hardware/Camera$Parameters;)V"); env->CallVoidMethod(cameraObject, setParametersMethodID, parametersObject); } ``` 以上代码中,我们通过调用 setExposureCompensation(int) 方法,将曝光补偿值设置为 0,来关闭曝光控制。具体实现中,我们使用了 JNI(Java Native Interface)来将 Java 代码与 C++ 代码连接起来。 在 Java 代码中,我们可以像下面这样调用 C++ 函数来关闭曝光控制: ``` setExposureCompensation(0); ``` 注意,这里的参数值为 0,表示关闭曝光控制。如果需要开启曝光控制,可以将参数值设置为一个正整数,表示曝光补偿值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

君莫笑lucky

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值