吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1664|回复: 4
收起左侧

[C&C++ 原创] 【Android】在 Android 应用中调用 C++ 代码并在新线程中执行 Java 静态方法

  [复制链接]
cnwutianhao 发表于 2023-4-19 16:54
本帖最后由 cnwutianhao 于 2023-4-20 16:03 编辑

Kotlin 代码:

package com.tyhoo.jni

import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.tyhoo.jni.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.sampleText.setOnClickListener {
            Log.d(TAG, "nativeMethod")
            nativeMethod()
        }
    }

    private external fun nativeMethod()

    companion object {
        private const val TAG = "Tyhoo"

        // Used to load the 'jni' library on application startup.
        init {
            System.loadLibrary("jni")
        }

        @JvmStatic
        fun staticMethod() {
            Log.d(TAG, "staticMethod")
        }
    }
}

这是 Kotlin 语言编写的 Android 应用程序中的 MainActivity 类,其中声明了一个名为 nativeMethod 的本地方法。该方法会在点击 sampleText 视图时被调用,从而触发 native 方法的执行。在 companion object 中还定义了一个名为 staticMethod 的静态方法,它会在应用程序启动时被加载,用于在 Java 层调用本地方法。这个静态方法可以从 Java 代码中直接调用,而不需要使用 JNI 接口函数。

C++ 代码:

#include <jni.h>
#include <string>
#include <android/log.h>

#define LOG_TAG "Tyhoo"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)

#define CLASSNAME "com/tyhoo/jni/MainActivity"

typedef struct {
    JavaVM *vm;
    jclass clazz;
} tyhoo_vm;

static tyhoo_vm javaVM;

JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *unused) {
    JNIEnv *env = nullptr;
    if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) {
        LOGD("JNI_OnLoad GetEnv failed\n");
        return -1;
    }

    jclass clazz = env->FindClass(CLASSNAME);
    if (!clazz) {
        LOGD("FindClass %s failed\n", CLASSNAME);
        return -1;
    }

    javaVM.vm = vm;
    javaVM.clazz = (jclass) env->NewGlobalRef(clazz);

    LOGD("JNI_OnLoad, vm: %p, clazz: %p \n", javaVM.vm, javaVM.clazz);
    return JNI_VERSION_1_6;
}

void JNI_OnUnload(JavaVM *vm, void *unused) {
    JNIEnv *env = nullptr;
    if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) {
        LOGD("JNI_OnLoad GetEnv failed\n");
        return;
    }
    env->DeleteGlobalRef(javaVM.clazz);
}

void callJavaStaticMethod() {
    JNIEnv *env = nullptr;
    jint res = javaVM.vm->AttachCurrentThread(&env, nullptr);
    if (res != JNI_OK) {
        return;
    }

    jclass clazz = javaVM.clazz;
    if (clazz == nullptr) {
        return;
    }

    jmethodID method = env->GetStaticMethodID(clazz, "staticMethod", "()V");
    env->CallStaticVoidMethod(clazz, method);
}

void *thread_func(void *arg) {
    callJavaStaticMethod();
    return nullptr;
}

extern "C"
JNIEXPORT void JNICALL
Java_com_tyhoo_jni_MainActivity_nativeMethod(JNIEnv *env, jobject thiz) {
    pthread_t thread;
    pthread_create(&thread, nullptr, thread_func, nullptr);
}

这是 C++ 语言编写的 JNI 接口函数,用于在 Java 层调用本地方法。这个接口函数的作用是创建新线程,并在新线程中调用 callJavaStaticMethod 方法,这个方法会获取当前线程的 JNIEnv 对象和 Java 类对象,并通过这些对象调用 Java 层的静态方法 staticMethod。

同步发布到我的 GitHub Blog 里:
https://github.com/cnwutianhao/blog/issues/1

免费评分

参与人数 1吾爱币 +7 热心值 +1 收起 理由
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

px307 发表于 2023-4-19 18:26
楼主真强,学以了,谢谢
xiexiaoxi 发表于 2023-4-19 19:23
Murph 发表于 2023-4-24 20:50
ax1xa 发表于 2024-7-15 14:39
谢谢大佬,感谢分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 13:24

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表