Android Java代码与JNI交互 JNI子线程访问Java方法 (八)

这篇具有很好参考价值的文章主要介绍了Android Java代码与JNI交互 JNI子线程访问Java方法 (八)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

🔥 Android Studio 版本 🔥  

Android Java代码与JNI交互 JNI子线程访问Java方法 (八),AndroidNDK,java,NDK,jni,android,c

🔥 创建包含JNI相关函数类 JNIInvokeMethod.java 🔥

package com.cmake.ndk1.jni;

import com.cmake.ndk1.base.ICallbackMethod;
import com.cmake.ndk1.base.IThreadCallback;

public class JNIInvokeMethod {
    static {
        System.loadLibrary("invoke-method-lib");
    }
    public native void nativeCallback(ICallbackMethod callback);
    public native void nativeThreadCallback(IThreadCallback callback);
}

 🔥 配置动态库名称 🔥 

add_library(
        #动态库名称 invoke-method-lib
        invoke-method-lib

        SHARED

        jni/jni_invoke_method.cpp
)

🔥 生成可关联的库链接 🔥 

为了让Java能够调用 invoke-method-lib 库中的函数,您需要使用 CMake 构建脚本中的 target_link_libraries() 命令来关联 invoke-method-lib 库

target_link_libraries( # Specifies the target library.
        ndk1
        person-lib
        dynamic-lib
        basic-type-lib
        string-lib
        reference-type-lib
        access-field-lib
        access-method-lib
        invoke-method-lib
        # Links the target library to the log library
        # included in the NDK. )
        )

 🔥 提供给Native调用的日志库链接 🔥

target_link_libraries( # Specifies the target library.
        invoke-method-lib
        # Links the target library to the log library
        # included in the NDK.
        ${log-lib})

 🔥 Native层实现 JNIInvokeMethod 类下面的JNI接口 🔥


#include <jni.h>
#include <base.h>
#include <pthread.h>


void *threadCallback(void *);

//全局变量
static jclass threadClazz;
static jmethodID threadMethod;
static jobject threadObject;

// Native中传一个接口和传一个类是一样的传法
extern "C"
JNIEXPORT void JNICALL
Java_com_cmake_ndk1_jni_JNIInvokeMethod_nativeCallback(JNIEnv *env, jobject instance,
                                                       jobject callback) {
    LOGD("nativeCallback");
    //获取 Object 赋值给 jclass
    jclass callbackClazz = env->GetObjectClass(callback);
    //通过 jclass 获取 methodID
    jmethodID callbackMethod = env->GetMethodID(callbackClazz, "callBack", "()V");
    // 通过 methodID 调用 callbackMethod
    env->CallVoidMethod(callback, callbackMethod);

}


/*
 * 声明 JavaVM 指针
 * 如何获取JavaVM?
 * 1.在JNI_OnLoad函数中获取
 * 2.(*env)->GetJavaVM(env,&javaVM);
 */
JavaVM *gVM;

extern "C"
JNIEXPORT void JNICALL
Java_com_cmake_ndk1_jni_JNIInvokeMethod_nativeThreadCallback(JNIEnv *env, jobject thiz,
                                                             jobject callback) {
    //NewGlobalRef 全局引用
    threadObject = env->NewGlobalRef(callback);
    threadClazz = env->GetObjectClass(callback);
    threadMethod=env->GetMethodID(threadClazz,"callback","()V");
    pthread_t handle;
    //线程创建
    pthread_create(&handle, nullptr, threadCallback, nullptr);

}

//我们之前回调Java函数都需要一个env的方法
//这里却没有,因为env是不跨线程的
//在加载so库的时候有一个JVM
//在jni_dynamic_load.cpp 文件里面有一个JNI_OnLoad 函数
//当调用JNI_OnLoad函数时候保存JVM的变量作为全局变量,下次通过JVM获取env
void *threadCallback(void *) {
    //获取Java的jvm实例
    //JavaVM *gVM = getJvm();
    //实现在子线程中拿到env
    JNIEnv *env = nullptr;
    // 返回成功是0
    if (gVM->AttachCurrentThread(&env, nullptr) == 0) {
        //实现回调Java方法
        env->CallVoidMethod(threadObject, threadMethod);

        //DetachCurrentThread()和AttachCurrentThread()配套使用
        gVM->DetachCurrentThread();
    }
    return 0;
}

JNIEXPORT
int JNICALL JNI_OnLoad(JavaVM *vm,void *reserved){
    gVM = vm;

    LOGD("jni onLoad call");
    return JNI_VERSION_1_6;
}

🔥 运行结果 🔥 

package com.cmake.ndk1;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import com.cmake.ndk1.base.ICallbackMethod;
import com.cmake.ndk1.base.IThreadCallback;
import com.cmake.ndk1.jni.JNIAccessMethod;
import com.cmake.ndk1.jni.JNIInvokeMethod;
import com.cmake.ndk1.model.Animal;

public class MainActivity8 extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final JNIInvokeMethod jniInvokeMethod = new JNIInvokeMethod();
        final TextView textView = findViewById(R.id.sample_text);
        textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                jniInvokeMethod.nativeCallback(new ICallbackMethod() {
                    @Override
                    public void callBack() {
                        Log.i("MainActivity8", "thread name is" + Thread.currentThread().getName());
                    }
                });
                jniInvokeMethod.nativeThreadCallback(new IThreadCallback() {
                    @Override
                    public void callback() {
                        Log.i("MainActivity8", "thread name is" + Thread.currentThread().getName());
                    }
                });
            }
        });
    }
}
D/LOG_JNI: nativeCallback
I/MainActivity8: thread name ismain
I/MainActivity8: thread name isThread-3

 下载案例文章来源地址https://www.toymoban.com/news/detail-568038.html

到了这里,关于Android Java代码与JNI交互 JNI子线程访问Java方法 (八)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android Java代码与JNI交互字符串转换(四)

    🔥 Android Studio 版本 🔥  🔥 创建JNIString.java 🔥  🔥 Native层实现 JNI的callNativeString函数 🔥 🔥 配置动态库名称 🔥  编辑CMakeLists.txt 根据j ni/jni_string.cpp 配置动态库名称  🔥 生成可关联的库链接 🔥 为了让Java能够调用 string-lib库中的函数,您需要使用 CMake 构建脚本中的 

    2024年02月13日
    浏览(37)
  • Android Java代码与JNI交互基础数据类型转换(三)

    🔥 Android Studio 版本 🔥  🔥 基础类型数据的转换 🔥 定义传递基础数据类型到Native的JNI接口函数 Native层创建callNativeInt 提供给Java调用 CMakeLists.txt 文件下配置动态库名称  添加 target_link_libraries 配置 Java调用Native层函数   运行打印日志 Java调用Native分别打印基础类型数据  下

    2024年02月13日
    浏览(30)
  • Android Studio 进行NDK开发,实现JNI,以及编写C++与Java交互(Java调用本地函数)并编译出本地so动态库

    1.首先认识一下NDK。 (1)什么是NDK? NDK全称是Native Development Kit,NDK提供了一系列的工具,帮助开发者快速开发C/C++的动态库,并能自动将so和java应用一起打包成apk。NDK集成了交叉编译器(交叉编译器需要UNIX或LINUX系统环境),并提供了相应的mk文件隔离CPU、平台、ABI等差异,

    2024年02月11日
    浏览(29)
  • Android JNI复杂用法,回调,C++中调用Java方法

    Android JNI的 普通用法估计很多人都会,但是C++中调用Java方法很多人不熟悉,并且网上很多介绍都是片段的。 虽然C/C++调用Java不常用,但是掌握多一点还是有好处的。 Android JNI的基础知识介绍,之前已经有介绍,不熟悉的可以先看看: Android Jni的介绍和简单Demo实现: https://

    2024年03月26日
    浏览(35)
  • Android和JNI交互 : 常见的图像格式转换 : NV21、RGBA、Bitmap等

    最近在使用 OpenCV 处理图片的时候,经常会遇到需要转换图像的情况,网上相关资料比较少,也不全,有时候得费劲老半天才能搞定。 自己踩了坑后,在这里记录下,都是我在项目中遇到的图像转化操作,是一些常用的图像格式转换操作。 具体包括: nv21、rgba、rgb 转换 OpenC

    2024年02月05日
    浏览(33)
  • Android JNI和原生交互,常见的图像格式转换 : NV21、RGBA、Bitmap等

    最近在使用 OpenCV 处理图片的时候,经常会遇到需要转换图像的情况,网上相关资料比较少,也不全,有时候得费劲老半天才能搞定。 自己踩了坑后,在这里记录下,都是我在项目中遇到的图像转化操作,是一些常用的图像格式转换操作。 具体包括: nv21、rgba、rgb 转换 OpenC

    2024年02月06日
    浏览(32)
  • Android:JNI实战,理论详解、Java与Jni数据调用

    上一篇博文《Android:JNI实战,加载三方库、编译C/C++》讲解了如何搭建一个可以加载和链接第三方库、编译 C/C++ 文件的 Jni Demo App。 这篇博文在这个 Jni Demo App 的基础上,从实战出发详细讲解  Jni  开发语法。 接下来,先用一小节将 Jni 开发比较重要的理论知识点过一下,然

    2024年01月23日
    浏览(35)
  • Android studio配置OpenCV的JNI接口,实现C++代码编程

    目录 一、下载OpenCV-android-sdk 二、新建项目 三、导入OpenCV包  四、配置OpenCV的JNI接口,拷贝OpenCV所需的头文件和库文件 五、修改Cmake文件  六、配置app的build.gradle文件  七、测试 OpenCV官网地址:https://opencv.org/  点击Library--Releases,下载Android版本,解压得到 OpenCV-android-sdk文件

    2024年02月10日
    浏览(31)
  • Android基于JNI的Java与C++互调

    java调用C++: //导出c函数格式 extern \\\"C\\\" JNIEXPORT //供JNI调用  JNICALL 函数名格式 Java_包名_类名_函数名(包名.替换为_) Java_com_example_getapplist_MainActivity_stringFromJNI    包名:com_example_getapplist   类名:MainActivity.      函数名:stringFromJNI C++ Jni  CMakeList.txt  

    2024年02月10日
    浏览(26)
  • Android蓝牙使能流程图(Android Bluetooth enable) -- java & jni层

    在介绍Android enable流程之前,我们首先来看下Android的流程图 以上图示是android8以上的,主要跟Android8之前的架构在于Bluetooth stack跟vendor层之间增加一层HIDL,主要是抽象硬件层的作用 OK,回归主题,我们来看下Android的enable流程,首先上一张架构图 另外声明下:我们做了一些列

    2024年02月09日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包