jni回调java方法

来源:互联网 发布:网络创世纪uo服务端 编辑:程序博客网 时间:2024/04/25 09:34

1、jni普通方法中回调java方法

static void android_server_LSPowerService_set_acc_callback(JNIEnv* env, jobject obj,jstring name)  {Mutex::Autolock l(sLock); const String8 nameString = Utility::getStringValue(env, name);jclass localRef = env->GetObjectClass(obj);jmethodID methodId = env->GetMethodID(localRef, nameString.string(), "(I)V");env->CallVoidMethod(obj, methodId, cAccStatus);}

2、jni线程中回调java方法

由于java调用jni时传递的JNIEnv和jobject会在jni返回时被释放,因此需要使用的参数申请全局的变量使用。可以参考如下例子:

#define LOG_TAG "LSPowerServicejni"#include "jni.h"#include "JNIHelp.h"#include "android_runtime/AndroidRuntime.h" #include <utils/Log.h> #include <ls/app_comm.h>  #include <stdio.h>#include <pthread.h>#include <sys/select.h>namespace android{    class Utility {    public:        static String8 getStringValue(JNIEnv* env, jobject object, const char* fieldName);        static char* getByteArrayValue(                JNIEnv* env, jobject object, const char* fieldName, int* dataLength);        static char* getByteArrayValue(                JNIEnv* env, jbyteArray byteArray, int* dataLength);        static String8 getStringValue(JNIEnv* env, jstring string);        static int getIntValue(JNIEnv* env, jobject object, const char* fieldName);    };    String8 Utility::getStringValue(JNIEnv* env, jobject object, const char* fieldName) {        /* Look for the instance field with the name fieldName */        jfieldID fieldID            = env->GetFieldID(env->GetObjectClass(object), fieldName , "Ljava/lang/String;");            if (NULL != fieldID) {            jstring valueString = (jstring) env->GetObjectField(object, fieldID);            return Utility::getStringValue(env, valueString);        }            String8 dataString("");        return dataString;    }        String8 Utility::getStringValue(JNIEnv* env, jstring string) {        String8 dataString("");            if (NULL != string && string != env->NewStringUTF("")) {            char* bytes = const_cast< char* > (env->GetStringUTFChars(string, NULL));                const int length = strlen(bytes) + 1;            char *data = new char[length];            strncpy(data, bytes, length);            dataString = String8(data);                env->ReleaseStringUTFChars(string, bytes);            delete [] data; data = NULL;        }        return dataString;    }        char* Utility::getByteArrayValue(                JNIEnv* env, jobject object, const char* fieldName, int* dataLength) {            *dataLength = 0;            jfieldID fieldID = env->GetFieldID(env->GetObjectClass(object), fieldName , "[B");            if (NULL != fieldID) {            jbyteArray byteArray = (jbyteArray) env->GetObjectField(object, fieldID);            return Utility::getByteArrayValue(env, byteArray, dataLength);        }        return NULL;    }        char* Utility::getByteArrayValue(JNIEnv* env, jbyteArray byteArray, int* dataLength) {        char* data = NULL;        if (NULL != byteArray) {            jint length = env->GetArrayLength(byteArray);                *dataLength = length;            if (0 < *dataLength) {                data = new char[length];                env->GetByteArrayRegion(byteArray, (jint)0, length, (jbyte *) data);            }        }        return data;    }        int Utility::getIntValue(JNIEnv* env, jobject object, const char* fieldName) {        jfieldID fieldID;        int intValue = -1;                    jclass clazz = env->GetObjectClass(object);        /* Look for the instance field with the name fieldName */        fieldID = env->GetFieldID(clazz, fieldName , "I");            if (NULL != fieldID) {            intValue = (int) env->GetIntField(object, fieldID);        }            return intValue;    }    class LsNativeMiscDevice{        protected:            class DoReadThread : public Thread {                private :                    bool                 mRequestExit;                    LsNativeMiscDevice*  mMiscDevice;                public:                    DoReadThread(LsNativeMiscDevice *dev)                         : Thread(false),mRequestExit(false),mMiscDevice(dev)  {                    }                                        ~DoReadThread()  {                        mRequestExit = false;                        mMiscDevice = NULL;                    }                                        void startThread() {                        run("LsPowerLoopThread", PRIORITY_URGENT_DISPLAY);                    }                                        void stopThread() {                        mRequestExit = true;                    }                                        virtual bool threadLoop() {                        if (mRequestExit) {                            return false;                        }                        return mMiscDevice ? mMiscDevice->readData() : false;                    }                        };            class DataCallBackDef : public RefBase{                protected:                                    JavaVM*     mJavaVM;                    jobject     mJavaObject;                    jmethodID   mMethodId;                                                                    public:                    DataCallBackDef(JNIEnv* env,jobject& obj,jmethodID methodId)  {                        if (env->GetJavaVM(&mJavaVM) < JNI_OK) {                            ALOGW("NativeActivity GetJavaVM failed");                            return;                        }                        mJavaObject = env->NewGlobalRef(obj);                            mMethodId = methodId;                    }                                        ~DataCallBackDef()  {                        mMethodId = NULL;                        mJavaVM = NULL;                        if(mJavaObject != NULL)  {                            JNIEnv *env = AndroidRuntime::getJNIEnv();                            env->DeleteGlobalRef(mJavaObject);                            mJavaObject = NULL;                            }                    }                    void callBack(const int value)  {                                                if(mJavaVM != NULL && mJavaObject != NULL)  {                            JNIEnv*     env;                            mJavaVM->AttachCurrentThread(&env, NULL);                            env->CallVoidMethod(mJavaObject, mMethodId, value);                            mJavaVM->DetachCurrentThread();                        }                                        }            };                    private:            pthread_rwlock_t            mRwLock;            sp<DoReadThread>            mReadThread;                sp<DataCallBackDef>         mShakeupCallBack;            JNIEnv*                     mEnv;        public:            LsNativeMiscDevice(JNIEnv *env) : mEnv(env)            {                mReadThread = new DoReadThread(this);                mShakeupCallBack = NULL;                pthread_rwlock_init(&mRwLock, NULL);            }            ~LsNativeMiscDevice()  {                if(mReadThread != NULL)  {                    mReadThread->stopThread();                    mReadThread.clear();                    mReadThread = 0;                }                if(mShakeupCallBack != NULL)  {                    mShakeupCallBack.clear();                    mShakeupCallBack = 0;                }                pthread_rwlock_destroy(&mRwLock);            }                void setShakeupCallBack(JNIEnv *env,jobject& obj,jmethodID id)  {                Mutex::Autolock locker(&mCallbackLock);                //create new                if(mShakeupCallBack != NULL)  {                    mShakeupCallBack.clear();                    mShakeupCallBack = 0;                                        }                mShakeupCallBack = new DataCallBackDef(env,obj,id);                ALOGD("end setShakeupCallBack\n");            }                        int startLoopData()  {                        Mutex::Autolock locker(&mObjectLock);                                                if(mReadThread != NULL)  {                     mReadThread->startThread();                }                return 0;            }            int stopLoopData()  {                Mutex::Autolock locker(&mObjectLock);                //stop thread.                if(mReadThread != NULL)  {                     mReadThread->stopThread();                }                return 0;            }            bool readData()  {                if(mShakeupCallBack != NULL)  {                   mShakeupCallBack->callBack(mShakeupStatus);                }                    return true;            }                    };    static LsNativeMiscDevice* mLsPowerDevice;    static Mutex sLock;    static void android_server_LSPowerService_set_shakeup_callback(JNIEnv* env, jobject obj,jstring name)  {        Mutex::Autolock l(sLock);         ALOGD("android_server_LSPowerService_set_shakeup_callback.");        if(mLsPowerDevice != NULL)  {            const String8 nameString = Utility::getStringValue(env, name);            jclass localRef = env->GetObjectClass(obj);            jmethodID methodId = env->GetMethodID(localRef, nameString.string(), "(I)V");                mLsPowerDevice->setShakeupCallBack(env,obj,methodId);                       }    }        };

相关推荐阅读资料:

http://m.android100.org/?host=www.android100.org&src=http%3A%2F%2Fwww.android100.org%2Fhtml%2F201308%2F19%2F3994.html

http://m.2cto.com/kf/201202/119764.html

0 0
原创粉丝点击