jni回撥java方法
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
相關文章
- JNI-Thread中start方法的呼叫與run方法的回撥分析thread
- java介面回撥Java
- Java——回撥機制Java
- Java--回撥模型Java模型
- java回撥函式Java函式
- java回撥函式-非同步回撥-簡明講解Java函式非同步
- java 介面回撥經典案例--網路請求回撥Java
- java 回撥函式示例Java函式
- JNI訪問Java方法Java
- java回撥函式機制Java函式
- Java回撥機制解讀Java
- Java回撥函式的理解Java函式
- Android 回撥方法的實現Android
- java閉包和回撥淺析Java
- Java 回撥機制(CallBack) 趣解Java
- Java介面回撥機制詳解Java
- 回撥函式透徹理解Java函式Java
- 深入淺出Java回撥機制Java
- 用 Java 實現回撥例程 (轉)Java
- [JS]回撥函式和回撥地獄JS函式
- 【JavaSE】java實現閉包與回撥Java
- Java中的閉包(Closure)和回撥Java
- 【JAVA】什麼叫回撥方法Java
- Flutter如何優雅的使用typedef回撥方法Flutter
- Activity生命週期回撥是如何被回撥的?
- java高階用法之:JNA中的回撥Java
- Java_介面回撥與匿名內部類Java
- 深入淺出: Java回撥機制(非同步)Java非同步
- Java 非同步回撥機制例項解析Java非同步
- 在Java中實現回撥過程 (轉)Java
- 回撥函式函式
- 微博回撥介面
- 非同步/回撥非同步
- JS 回撥模式JS模式
- C++回撥C++
- js 回撥 callbackJS
- react-native呼叫ios native方法-回撥ReactiOS
- append2 給append 新增回撥方法APP