Created
February 20, 2020 13:35
-
-
Save KeyYao/7934107c73539aaeb6014b1c4527171a to your computer and use it in GitHub Desktop.
JNIEnvHandler
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Created by Key.Yao on 2020-02-20. | |
// | |
#include "JNIEnvHandler.h" | |
using namespace std; | |
struct ThreadMessage { | |
ThreadMessage(int i, void* m, bool flag) { | |
what = i; | |
msg = m; | |
exit = flag; | |
} | |
int what; | |
void* msg; | |
bool exit; | |
}; | |
JNIEnvHandler::JNIEnvHandler(const char *threadName) { | |
_threadName = threadName; | |
_thread = nullptr; | |
_exitFlag = false; | |
_vm = nullptr; | |
_callback = nullptr; | |
} | |
JNIEnvHandler::~JNIEnvHandler() { | |
_thread = nullptr; | |
_callback = nullptr; | |
_instance = nullptr; | |
_vm = nullptr; | |
} | |
bool JNIEnvHandler::init(JavaVM *vm, jobject instance, handleMessage callback) { | |
if (!_thread) { | |
_thread = new thread(&JNIEnvHandler::process, this); | |
} | |
_vm = vm; | |
_instance = instance; | |
_callback = callback; | |
return true; | |
} | |
void JNIEnvHandler::exit() { | |
if (!_thread) { | |
return; | |
} | |
auto *msg = new ThreadMessage(-1, nullptr, true); | |
{ | |
lock_guard<mutex> lock(_mutex); | |
_queue.push(msg); | |
_cv.notify_one(); | |
} | |
_thread->join(); | |
delete _thread; | |
_thread = nullptr; | |
_exitFlag = true; | |
} | |
std::thread::id JNIEnvHandler::getThreadId() { | |
return _thread->get_id(); | |
} | |
void JNIEnvHandler::post(int what, void *obj) { | |
auto *msg = new ThreadMessage(what, obj, false); | |
unique_lock<mutex> lock(_mutex); | |
_queue.push(msg); | |
_cv.notify_one(); | |
} | |
void JNIEnvHandler::process() { | |
_exitFlag = false; | |
JNIEnv *env = nullptr; | |
if (_vm) { | |
_vm->AttachCurrentThread(&env, nullptr); | |
} | |
while (true) { | |
ThreadMessage *msg = nullptr; | |
{ | |
unique_lock<mutex> lock(_mutex); | |
while (_queue.empty()) { | |
_cv.wait(lock); | |
} | |
if (_queue.empty()) { | |
continue; | |
} | |
msg = _queue.front(); | |
_queue.pop(); | |
} | |
if (msg->exit) { | |
delete msg; | |
break; | |
} | |
if (env && _instance) { | |
_callback(msg->what, msg->msg, env, _instance); | |
} | |
delete msg; | |
} | |
env->DeleteGlobalRef(_instance); | |
if (_vm) { | |
_vm->DetachCurrentThread(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Created by Key.Yao on 2020-02-20. | |
// | |
#ifndef __JNIENVHANDLER_H__ | |
#define __JNIENVHANDLER_H__ | |
#include <jni.h> | |
#include <thread> | |
#include <queue> | |
#include <atomic> | |
#include <condition_variable> | |
typedef void(*handleMessage)(int what, void* obj, JNIEnv *env, jobject instance); | |
struct ThreadMessage; | |
class JNIEnvHandler { | |
public: | |
JNIEnvHandler(const char* threadName); | |
~JNIEnvHandler(); | |
bool init(JavaVM *vm, jobject instance, handleMessage callback); | |
void exit(); | |
std::thread::id getThreadId(); | |
void post(int what, void *obj = nullptr); | |
private: | |
JNIEnvHandler(const JNIEnvHandler&); | |
JNIEnvHandler&operator=(const JNIEnvHandler&); | |
void process(); | |
JavaVM *_vm; | |
jobject _instance; | |
std::thread *_thread; | |
std::queue<ThreadMessage*> _queue; | |
std::mutex _mutex; | |
std::condition_variable _cv; | |
std::atomic<bool> _exitFlag; | |
handleMessage _callback; | |
const char* _threadName; | |
}; | |
#endif //__JNIENVHANDLER_H__ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment