- 首先定义事件枚举:
enum EventEnum {
eeSleepWake,
};
- 其次,定义一个函数指针:
typedef void (onSleepWake)(int code, void sender);
这个函数指针可以指向一个返回值为void 参数分别为 int 和void_型指针的函数,其中void_型指针表示调用方的指针
- 定义一个结构体,包含函数指针和调用方的指针
struct EventData {
void* eventPointer;
void* sender;
};
- 注册事件持有类,使其成为单例
这个操作的部分代码:
class EventManager {
public:
static EventManager& singleton()
{
static EventManager sl;
return sl;
}
static EventManager& getInstance()
{
return singleton();
}
//注册事件
void addEvent(EventEnum eventEnum, void* event, void* sender);
EventData getEventData(EventEnum eventEnum);
private:
std::map<EventEnum, EventData> eventMap;
EventManager(){};
~EventManager(){};
};
- 实现事件注册函数
void EventManager::addEvent(EventEnum eventEnum, void* event, void* sender) {
if(event == nullptr || sender == nullptr) {
return;
}
EventData eventData;
eventData.eventPointer = event;
eventData.sender = sender;
eventMap.insert(std::pair<EventEnum, EventData>(eventEnum, eventData));
}
- 编写函数指针对应函数的具体实现
void eeSleepWakeCallback(int result, void* sender) {
JniTester *tester = (JniTester *) sender;
tester->onResultCallback(result);
}
- 在入口类中注册事件及其对应的枚举和函数
JniTester::JniTester() {
EventManager::getInstance().addEvent(eeSleepWake, (void*)eeSleepWakeCallback, this);
}
- 编写异步函数调用
··· void JniTester::getThreadResult() { ThreadTest *test = new ThreadTest(); test->sleepThread(); } ··· 耗时函数的具体实现:
void ThreadTest::sleepThread() {
std::thread cal_task(&ThreadTest::makeSleep, this);
cal_task.detach();
}
void Threa
dTest::makeSleep() {
sleep(2);
}
这一步我们是通过新建一个线程,并让其等待2S来模拟异步耗时操作
=========================================================================
- 在java层编写java的回调方法
private OnResultCallback callback;
public void setOnResultCallback(OnResultCallback callback) {
this.callback = callback;
}
public interface OnResultCallback {
void onResult(int result);
}
- 在java曾编写java层回调的触发:
public void onResult(int result) {
if (this.callback != null) {
callback.onResult(result);
}
}
- native层异步动作完成的通知
通过向单例的事件持有类获取对应的事件枚举,获取到其对应的函数指针,并调用该函数指针实现:
void ThreadTest::makeSleep() {
sleep(2);
EventData eventData = EventManager::singleton().getEventData(eeSleepWake);
onSleepWake wake = (onSleepWake)eventData.eventPointer;
if(wake) {
wake(12345, eventData.sender);
}
}
因为我们在第三章节第7步注册的函数指针是eeSleepWakeCallback, 因此,这里会调用到这个函数:
void eeSleepWakeCallback(int result, void* sender) {
JniTester *tester = (JniTester *) sender;
tester->onResultCallback(result);
}
通过sender确定具体的对象,调用其onResultCallback函数
- onResultCallback函数的实现
void JniTester::onResultCallback(int result) {
JNIEnv *env = NULL;
int status = f_jvm->GetEnv((void **) &env, JNI_VERSION_1_4);
bool isInThread = false;
if (status < 0) {
isInThread = true;
f_jvm->AttachCurrentThread(&env, NULL);
}
if (f_cls != NULL) {
jmethodID id = env->GetMethodID(f_cls, “onResult”, “(I)V”);
if (id != NULL) {
env->CallVoidMethod(f_obj, id, result);
}
}
最后
小编这些年深知大多数初中级Android工程师,想要提升自己,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人
都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
资料⬅专栏获取
);
if (id != NULL) {
env->CallVoidMethod(f_obj, id, result);
}
}
最后
小编这些年深知大多数初中级Android工程师,想要提升自己,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
[外链图片转存中…(img-3aK3QKM9-1719093654677)]一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人
都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
资料⬅专栏获取