完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
名词解释
AliOS Things: 阿里云智能IoT团队自研的物联网操作系统 HaaS:全称是Hardware as a Service,阿里云智能IoT团队基于AliOS Things系统推出的硬件即服务 HaaS UI:全称是Hardware as a Service User Interface,是源自AliOS Things操作系统上的一套应用&图形解决方案,支持C/C++和 JS两种开发语言 JSAPI注册&实现 在HaaS UI基础教学中,我们已经学会了开发一个Native的模块给JS调用,现在让我们模拟一下文件下载功能来回顾一下JSAPI的注册和实现; 1. 注册: void register_download_jsapi() { ariver::iot::ExtensionProxyBase* proxy = getJSApiExtensionProxy(); proxy->REGISTER_JSAPI(&BrightnessApiExtension::download, Download, download); } 其中第二个参数Download是模块名,第三个参数download是在js中方法名,第一个参数BrightnessApiExtension::download是其对应的方法; 2. 实现: string downloadFile(string url) { string content; // implement download & store to content return content; } void DownloadApiExtension::download(const std::string& callbackId, const std::string& params) { ariver::iot::ExtensionProxyBase* proxy = ariver::iot::getJSApiExtensionProxy(); std::string error; JQuick::Json jsonParams; JQuick::Json::object failJson; JQuick::Json::object jsonCallback; APIStatus status = API_Success; JQuick::Json::object data; JQuick::Json::object::iterator dataIter; JQuick::Json result; std::string url; jsonParams = JQuick::Json::parse(params, error); if (!error.empty()) { failJson["errorMessage"] = JQuick::Json(std::string("params must be json format!")); goto Fail; } url = jsonParams["url"].string_value(); if (url.empty()) { failJson["errorMessage"] = JQuick::Json(std::string("parameter error")); goto Fail; } jsonCallback["result"] = downloadFile(url); result = JQuick::Json(jsonCallback); proxy->postCallback(callbackId, status, result.dump()); return; Fail: jsonCallback["result"] = failJson; result = JQuick::Json(jsonCallback); status = API_Failed; proxy->postCallback(callbackId, status, result.dump()); } 至此,我们实现了JSAPI的下载功能,但是在运行过程中我们发现,downloadFile函数运行时间会因为url对应的文件大小同步,网络状态的不同,所花时间有很大的波动,在此期间整个小程序都没有反应,用户体验很差,在实现JSAPI方法中有耗时的函数,都会有类似的问题;那我们怎么解决呢? 3. 子线程实现JSAPI 从上面实现我们可以看出,时间主要消耗在downloadFile,在下载完成后,通过 proxy->postCallback(callbackId, status, result.dump()); 把结果返回给JS层,callbackId是Native回调JS的锚点,为了不影响JS响应,我们需要要将下载改为子线程实现: class downloadArgs { public: downloadArgs(string url, string callbackId) : mUrl(url), mCallbackId(callbackId) {} string mUrl; string mCallbackId; }; string downloadFile(string url) { string content; // implement download & store to content printf("complete download url: %sn", url.c_str()); content = "url: " + url + " has be downloaded"; return content; } void* downloadTask(void* arg) { downloadArgs* args = (downloadArgs*)arg; ariver::iot::ExtensionProxyBase* proxy = ariver::iot::getJSApiExtensionProxy(); JQuick::Json::object jsonCallback; JQuick::Json result; APIStatus status = API_Success; jsonCallback["result"] = downloadFile(args->mUrl); result = JQuick::Json(jsonCallback); proxy->postCallback(args->mCallbackId, status, result.dump()); printf("has postCallbackn"); delete args; return nullptr; } void DownloadApiExtension::download(const std::string& callbackId, const std::string& params) { printf("enter downloadn"); ariver::iot::ExtensionProxyBase* proxy = ariver::iot::getJSApiExtensionProxy(); std::string error; JQuick::Json jsonParams; JQuick::Json::object failJson; JQuick::Json::object jsonCallback; APIStatus status = API_Success; JQuick::Json::object data; JQuick::Json::object::iterator dataIter; JQuick::Json result; std::string url; downloadArgs* args; jsonParams = JQuick::Json::parse(params, error); if (!error.empty()) { failJson["errorMessage"] = JQuick::Json(std::string("params must be json format!")); goto Fail; } url = jsonParams["url"].string_value(); if (url.empty()) { failJson["errorMessage"] = JQuick::Json(std::string("parameter error")); goto Fail; } args = new downloadArgs(url, callbackId); jquick_thread_create("download", &downloadTask, args); return; Fail: jsonCallback["result"] = failJson; result = JQuick::Json(jsonCallback); status = API_Failed; proxy->postCallback(callbackId, status, result.dump()); } 我们在DownloadApiExtension::download中启动子线程进行下载,在下载完成后调用postCallback把结果返回JS,这样整个应用不会因为下载而卡住; JSAPI调度 在我们框架中,所有JS都同一个线程中运行,即使我们在子线程中调用postCallback回调JS,最终JS的执行也是在JS线程中,看下JS中执行情况: { $falcon.jsapi.Download.download({url:"http://aiot.aliyun.com/mini_app/list.json"}, (result) => { console.log(">>>result: ", result) }); console.log("run here"); } 运行结果如下: 从打印的顺序可以看出,虽然$falcon.jsapi.Download.download在最前面,但是download的native代码并没有执行,所以console.log("run here")最先打印出来,$falcon.jsapi.Download.download只是给JS线程发送了一个消息;同样在native代码中,postCallback也只是给js线程抛了一个消息; 所以我们在JS中调用JSAPI时,一定要注意代码执行顺序; 小结
文章转载自:平头哥芯片开放社区 作者:sucool |
|
相关推荐
|
|
只有小组成员才能发言,加入小组>>
【平头哥Sipeed LicheeRV 86开发板试用体验】Waft初体验
15706 浏览 1 评论
13761 浏览 4 评论
【平头哥Sipeed LicheeRV 86开发板试用体验】四、烧写waft系统&搭建waft测试环境
19682 浏览 2 评论
59126 浏览 19 评论
【限时福利】加入芯片开发社区,领100G电子工程师资料大礼包
88185 浏览 121 评论
邀请函 | 3月2日 来上海参加平头哥“玄铁RISC-V生态大会”
787浏览 0评论
读书分享会 | 玄铁RISC-V处理器入门与实战电子书免费下载!
684浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 19:09 , Processed in 0.663956 second(s), Total 69, Slave 52 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号