android使用c通過jni回調java

來源:互聯網
上載者:User

標籤:des   android   style   color   io   使用   java   ar   for   

很多場合都有這樣的需求,由於以前都是java調用c的介面,沒有做過回調,今天花了大半天時間把這個流程跑通了,記錄一下,以備後用。這裡發句牢騷,那些網上分享出來的代碼,請問你們確實是能正常工作嗎?還有查來查去都是那幾份,大家轉載精神可嘉啊

jni相關標頭檔代碼

/* DO NOT EDIT THIS FILE - it is machine generated */#include/* Header for class com_example_ndktest_CallbackTest */#ifndef _Included_com_example_ndktest_CallbackTest#define _Included_com_example_ndktest_CallbackTest#ifdef __cplusplusextern "C" {#endif/** Class: com_example_ndktest_CallbackTest* Method: start* Signature: ()V*/JNIEXPORT void JNICALL Java_com_example_ndktest_CallbackTest_start(JNIEnv *, jobject);#ifdef __cplusplus}#endif#endif




具體實現代碼

 #include<stdlib.h>#include<pthread.h>#include<jni.h>#include<android/log.h>#include "com_example_ndktest_CallbackTest.h"#define LOG_TAG "jni"#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");    int i;    for(i = 0; i < 100; i++){        jstring jstr = (*evn) -> NewStringUTF(evn, "I am Fengfei");        LOGD("invoke callback");        (*evn)->CallVoidMethod(evn, mobj, mid, jstr);        jthrowable exception = (*evn)->ExceptionOccurred(evn);        if (exception) {            (*evn)->ExceptionDescribe(evn);        }        sleep(2);     }    if(needsDetach)        (*m_vm)->DetachCurrentThread(m_vm);}JNIEXPORT void JNICALL Java_com_example_ndktest_CallbackTest_start(JNIEnv *evn, jobject object){LOGD("call start");    //在子線程中不能這樣用    //jclass tclass = (*evn)->FindClass(evn, "com/example/ndktest/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);}

java代碼(具體怎麼產生.so,參看android ndk使用)

package com.example.ndktest;public class CallbackTest {static {    System.loadLibrary("callback");}public native void start();public void callback(String str){    System.out.println(str);}}



android使用c通過jni回調java

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.