第一阶段学习 LuaView,已经对其有一定的了解:什么是LuaView、LuaViewCore,自定义控件的桥接等。(详见 LuaView初识)此部分主要对 LuaViewSDK 自带的调试工具 LuaViewDebugger 和 如何下载 Server 端的 Lua 脚本进行 Native 界面的渲染做记录。
LuaViewDebugger
LuaViewDebugger 是 LuaViewSDK 提供的 Lua 脚本调试工具。因为在 Xcode 上无法断点调试 Lua 脚本,用指令调试又显得麻烦。LuaViewDebugger 刚好解决了 Lua 脚本断点调试的问题。
但是这个工具功能也过于简单了些。和 LuaViewSDK 官方人员聊了下,其实就是对 Lua 调试指令做了一次封装而已,没有其他扩展功能。
启动这个 LuaViewDebugger ,Mac OS 下需要下载 JDK 的支持,JDK 下载地址 。点击启动 LuaViewDebugger 如下图所示:
此时在项目里面随意 run 一个 Lua 脚本,LuaViewDebugger 就会展开成如下界面,
可以进行断点调试,也可以点击变量打印。其他也没啥功能了。目前 Android 端是无法用此工具进行调试。和官方人员聊,其意思是不建议用这个做调试,可能存在某些未知问题吧。
最开始想实现断点调试,�由于官方没有 Debugger 相关的文档,故自己去琢磨其 SDK 的 Debuger 类源码,从中分析用法。本地搭建个服务器,设置好端口和 IP ,调试器设置为开启,demo 跑起来后,套接字创建好,也成功链接,run了一个脚本,发现最后一直在 DebugReadCmd 和 DebugSleep 俩方法死循环,界面也没渲染成功,卡死在那。后来不明所以询问官方人员,就叫使用其提供的 Debug 服务器。如有此方面经验的,麻烦告知我自己实现错在哪里,谢谢!
Download
之前运行的脚本都是放在项目的本地目录下。实际运用中,脚本会放在 Server 端,进行动态下发,Native 下载好脚本后进行界面渲染等操作。
搭建本地服务器
网上有很多搭建本地服务器的方法,在此就不多说了。下面是我的配置 json
将 Lua 脚本放到服务器目录下,终端输入 npm run serveapp 启动服务器。
Native 下载 Server 端的 Lua 脚本资源
Demo 中,我直接尝试下载服务器的脚本 zip 包,然后本地解压:
- (void)loadData{
NSString*urlStr = luaResourceUrlStr;
NSString*saveZipFilePath = [[[NSBundlemainBundle]bundlePath]stringByAppendingString:@"XQOnlineLuas.zip"];
NSString*saveUnzipFilePath = [[NSBundlemainBundle]bundlePath];
BOOLloadZipSucess = [XQDataHelperloadZipLuaFilesWithUrl:urlStrsavePath:saveZipFilePath];
if(loadZipSucess) {
NSArray*ary = [XQDataHelperunzipFileWithFilePath:saveZipFilePathpath:saveUnzipFilePath];
if(ary) {
NSLog(@"解压成功,解压的文件是:\n %@",ary);
}
}
}
其中下载方法:
+ (BOOL)loadZipLuaFilesWithUrl:(NSString *)urlStr savePath:(NSString*)savePath{
if(urlStr.length==0|| savePath.length==0) {
returnNO;
}
NSURL*url = [NSURL URLWithString:urlStr];
NSURLRequest*request = [NSURLRequest requestWithURL:url];
NSError*error =nil;
NSData*data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&error];
if(data !=nil){
NSLog(@"下载成功");
NSString *filePath = savePath;
sucess = [datawriteToFile:filePathatomically:YES];
}else{
NSLog(@"%@", error);
}
return sucess;
zip 包解压我使用了第三方的 ZipArchive(SDK 里也有官方提供的 LVPkgManager 类可用于解压)。解压方法:
+ (NSArray*)unzipFileWithFilePath:(NSString*)zipFilePath path:(NSString*)unzipFilePath{
BOOLsucess =NO;
ZipArchive*zip = [[ZipArchivealloc]init];
if([zipUnzipOpenFile:zipFilePath]) {
sucess = [zipUnzipFileTo:unzipFilePathoverWrite:YES];
if(!sucess) {
[zipUnzipCloseFile];
}
}
if(sucess) {
NSLog(@"解压保存成功.");
return[zipgetZipFileContents];
}
else{
NSLog(@"解压保存失败.");
returnnil;
}
}
@end
由此实现 Native 下载服务器的 zip 脚本包,然后解压存储,读取运行,实现 lua 脚本控制 Native 的界面渲染等。
扩展 —— 脚本控制下载脚本,并运行
在实现本地下载脚本的时候,突然有个想法:能否实现 run 一个脚本 a,这个脚本 a 的作用是去服务器下载脚本 b,脚本 b 才是控制界面渲染的,a 控制下载 b 成功后,直接运行脚本 b。
当然这个官方文档也没用相关说明,只能从源码入手查找思路。结果照了半天没找到,求助官方群。官方人员解答其 demo 里有个 dynamicsCode.lua 就是实现想法中 a 的功能。结果搜寻了下此脚本,发现 iOS 的 demo 里面没有这个脚本,只有 android 的 demo 目录里有个 NUI_DynamicCode.lua 文件。关键方法如下:
查找其 SDK 里对应的 load 相关源码,发现了如下所示:
脚本里加载另一个脚本的方法有如下三种:
loadfile :参数是需要加载的脚本的路径
load:参数是需要加载的脚本方法
loadstring:参数是需要加载的脚本内容
注:android 的 SDK 源码中此处有点不同。android 中只有 loadfile 和 load,其中 load 的参数可以是方法也可以是脚本内容,故 android 端的 load 等同于 iOS 端的 load 和 loadstring。所以在写一份脚本两端使用时,若使用 loadstring ,android端是无法识别的。
我的demo中,分别对以上三种方式做了尝试:
XQLuaLoad.lua 脚本是负责下载 server 端脚本 online0.lua ,并运行。
--待下载的脚本url
fileUrl = "http://xxxxx/XQOnline0.lua"
Download( fileUrl,"online0.lua",
function (data)
print( data );
--使用loadstring的方式加载下载的脚本,并运行
online0 = loadstring(tostring(data));
online0();
end);
XQLuaLoad.lua 可以放在项目本地目录,也可以放在 server 端,Native 需要先下载运行 XQLuaLoad.lua。该脚本中,我用了 SDK 中 LVDownloader 类的下载方法。当然如 LuaView初识 描述的,你也可以自定义下载方法,然后桥接到 Lua 环境中即可在脚本中使用。
Demo 效果如下:
如有纰漏,欢迎指出,谢谢!