Android :JNI 回调demo

                        Android :JNI 回调demo

一、AndroidStudioProjects\jnicallbackdemo\app\src\main\java\com\example\jnicallbackdemo\MainActivity.java

package com.example.jnicallbackdemo;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
   // Callbacktest m_nextouch =new Callbacktest();
    int n=0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
       // m_nextouch.start();
        start();
    }
    static {
        System.loadLibrary("callback");
    }
    public native void start();

    public void callback(String str){
        System.out.println("information from jni callback:"+str+"  number="+n);
        n++;
    }
}

二、AndroidStudioProjects\jnicallbackdemo\app\src\main\jni\com_example_jnicallbackdemo_MainActivity.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_jnicallbackdemo_MainActivity */

#ifndef _Included_com_example_jnicallbackdemo_MainActivity
#define _Included_com_example_jnicallbackdemo_MainActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_example_jnicallbackdemo_MainActivity
 * Method:    start
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_example_jnicallbackdemo_MainActivity_start
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

三、AndroidStudioProjects\jnicallbackdemo\app\src\main\jni\com_example_jnicallbackdemo_Callbacktest.c

#include<stdlib.h>
#include<pthread.h>
#include<jni.h>
#include<android/log.h>
//#include "com_example_jnicallbackdemo_Callbacktest.h"

#include "com_example_jnicallbackdemo_MainActivity.h"
#define LOG_TAG "JNICALLBACK"


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


jmethodID mid;
jclass objclass;
jobject mobj;
pthread_t thread;
JavaVM *m_vm;


//初始化的时候会调进来一次,在这个方法里持有jvm的引用
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved){
    m_vm=vm;
    JNIEnv* env = NULL;
    jint result = -1;
    if(m_vm){
        LOGD("m_vm init success");
    }else{
        LOGD("m_vm init failed");
    }
    if ((*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_4) != JNI_OK){
        return result;
    }
    return JNI_VERSION_1_4;
}
JNIEnv* getJNIEnv(int* needsDetach){
    JNIEnv* env = NULL;
    jint result = -1;
    if ((*m_vm)->GetEnv(m_vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK){
        int status = (*m_vm)->AttachCurrentThread(m_vm, &env, 0);
        if (status < 0){
            LOGD("failed to attach current thread");
            return NULL;
        }
        *needsDetach = 1;
    }
    LOGD("GetEnv Success");
    return env;
}

void *thread_run(){
    LOGD("thread start");
    int needsDetach;
    JNIEnv *evn=getJNIEnv(&needsDetach);
    LOGD("start noop callback");
    while(1)
    {
        jstring jstr = (*evn) -> NewStringUTF(evn, "I am from JNI !");
        LOGD("invoke callback");
        (*evn)->CallVoidMethod(evn, mobj, mid, jstr);
        jthrowable exception = (*evn)->ExceptionOccurred(evn);
        if (exception) {
            (*evn)->ExceptionDescribe(evn);
        }
        usleep(1000*250);
        (*evn) -> DeleteLocalRef(evn, jstr);
     }
    if(needsDetach)
        (*m_vm)->DetachCurrentThread(m_vm);
}


//JNIEXPORT void JNICALL Java_com_example_jnicallbackdemo_Callbacktest_start(JNIEnv *evn, jobject object){
JNIEXPORT void JNICALL Java_com_example_jnicallbackdemo_MainActivity_start(JNIEnv *evn, jobject object){
     LOGD("call start");
    //在子线程中不能这样用
    //jclass tclass = (*evn)->FindClass(evn, "com/example/jnicallbackdemo/CallbackTest");
    //这种写法可以用在子线程中
    objclass=(*evn)->GetObjectClass(evn, object);
    mid = (*evn)->GetMethodID(evn, objclass, "callback", "(Ljava/lang/String;)V");

    //JNI 函数参数中 jobject 或者它的子类,其参数都是 local reference。Local reference 只在这个 JNI函数中有效,JNI函数返回后,引用的对象就被释放,它的生命周期就结束了。若要留着日后使用,则需根据这个 local reference 创建 global reference。Global reference 不会被系统自动释放,它仅当被程序明确调用 DeleteGlobalReference 时才被回收。(JNI多线程机制)
    mobj=(*evn)->NewGlobalRef(evn, object);
    pthread_create(&thread, NULL, thread_run, NULL);
}

四、代码图

五、运行效果

六、源码下载路径:https://download.csdn.net/download/qq_37858386/12890125

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值