写点什么

[Android] 使用函数指针实现 native 层异步回调,鸿蒙 app 开发工具

用户头像
Android架构
关注
发布于: 23 小时前

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));


}


  1. 编写函数指针对应函数的具体实现


void eeSleepWakeCallback(int result, void* sender) {


JniTester *tester = (JniTester *) sender;


tester->onResultCallback(result);


}


  1. 在入口类中注册事件及其对应的枚举和函数


JniTester::JniTester() {


EventManager::getInstance().addEvent(eeSleepWake, (void*)eeSleepWakeCallback, this);


}


  1. 编写异步函数调用


··· void JniTester::getThreadResult() { ThreadTest *test = new ThreadTest(); test->sleepThread(); } ··· 耗时函数的具体实现:


void ThreadTest::sleepThread() {


std::thread cal_task(&ThreadTest::makeSleep, this);


cal_task.detach();


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


}


void ThreadTest::makeSleep() {


sleep(2);


}


这一步我们是通过新建一个线程,并让其等待 2S 来模拟异步耗时操作


[](


)4. 异步回调的实现


=========================================================================


  1. 在 java 层编写 java 的回调方法


private OnResultCallback callback;


public void setOnResultCallback(OnResultCallback callback) {


this.callback = callback;


}


public interface OnResultCallback {


void onResult(int result);


}


  1. 在 java 曾编写 java 层回调的触发:


public void onResult(int result) {


if (this.callback != null) {


callback.onResult(result);


}


}


  1. 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 函数


  1. 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);


}


}


if (isInThread) {


f_jvm->DetachCurrentThread();


}


}


这里因为缺少 java 环境,因此我们需要将该线程挂载到 jvm 上执行,并获取对应的 JNIEnv ,通过 jnienv 获取 java 层的回调触发方法 onResult 并执行。


[](


)5.效果


==================================================================


编写测试代码:


JniTester tester = new JniTester();


Log.d("zyl", "startTime = " + System.currentTimeMillis());


tester.setOnResultCallback(result -> {


Log.d("zyl", "endTime = " + System.currentTimeMillis());


Log.d("zyl", "result = " + result);


});

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
[Android]使用函数指针实现native层异步回调,鸿蒙app开发工具