袁卉欣,叶德建
随着移动互联网时代的到来,人们对智能移动设备的需求越发强烈。同时,很多传统企业也争相投入到移动互联网行业中。这些都造成了移动应用市场的需求越来越大,竞争越发激烈,对应用开发人员的要求也越来越高。但是,目前移动应用的开发中却存在着一些问题,如技术门槛高、开发效率低、开发维护成本高等。并且,一般开发人员在对已上市的移动应用进行优化时也缺乏对其真实使用情况的深入了解。这些问题都阻碍了移动应用市场的发展。
当前主要的移动应用开发方式有原生应用开发、Web应用开发、混合应用开发3种方式[1]。其中,原生应用性能最好,但跨平台性差,开发维护成本高;Web应用开发成本低、效率高、跨平台性好,但是,性能以及用户体验不理想;混合式应用充分结合了前两者的优势[2],是移动应用开发新的趋势。不过,混合式应用开发却需要同时进行前端代码和原生代码的编写,对开发人员的要求较高。因此,目前已经有一些支持混合式应用开发的框架出现,但或多或少都存在一些问题,使用起来不是很方便。此外,国内也出现了一些帮助开发人员收集用户使用数据的工具,但这些工具都需要手动在需要监测的地方添加相应的代码,使用繁琐,而且容易出错导致收集的数据不准确。
本文的应用引擎系统就是为了解决这些问题而出现的。应用引擎系统包含了应用引擎以及基于应用引擎的IDE,应用引擎采用了混合式应用的方式并将原生代码相关的部分进行了封装,集成了API封装模块、云模块以及设备互联模块等;IDE在基本的应用代码编辑、编译发布等功能外提供了可视化开发功能。本文第一章将介绍应用引擎的设计与实现;第二章将阐述基于应用引擎的IDE的设计与实现;第三章将会对系统进行实验验证,证明其确实能够帮助开发人员快速方便地开发移动应用并获取用户数据;最后,第四章本文将给出总结与展望。
应用引擎的整体架构设计如图1所示:
图1 应用引擎的架构设计图
从结构上来看,应用引擎相当于中间件,位于平台系统库和Web页面之间,并和Web页面共同组成了混合式移动应用。图1中平台系统库可以分为核心功能库、浏览器引擎、图形库以及第三方库,核心功能库提供核心的系统功能,如文件系统、网络连接等,浏览器引擎和图形库为混合式应用提供了运行时的环境支持。
应用引擎包含5大模块:平台功能模块、云模块、设备互联模块、API封装模块以及Web库模块。
(1)平台功能模块对平台系统层的核心功能的调用接口进行了封装,为应用开发人员提供了适合在Web页面调用的常用的平台功能接口。
(2)云模块借助清鹤云平台,可以提供常规的分布式存储等云服务并自动收集用户的使用数据上传到云平台进行分析。
(3)设备互联模块基于UPnP协议,可以帮助移动应用实现设备的互联互通,方便地与其他智能设备进行多媒体文件的共享。
(4)API封装模块则是将这些模块提供的功能接口统一封装成前端代码可以调用的JavaScript接口以供开发人员在Web页面中直接调用。
(5)Web库模块则提供了混合式移动应用开发过程中常用的HTML控件以及CSS格式,方便应用界面的开发。
接下来本文将详细阐述关键的API封装以及数据收集分析功能的具体设计及实现。
Android中的 WebView 组件提供了原生的AddJavascriptInterface方法用于实现原生Java代码和Web页面的交互,但该方案在Android4.2以下的版本中存在很大的安全隐患。如果攻击者在页面执行一些非法的JavaScript代码,极有可能通过Java的反射机制拿到手机的shell权限,获取敏感信息[3]。因此,应用引擎需要针对Android4.2以下的版本设计Web页面和原生代码的交互方案。
在Android操作系统中,除了addJavaScriptInterface方法外,还有几种方法涉及到Java和JavaScript之间的交互,其中 prompt能够进行前端代码和原生代码之间消息的双向传输。因此,应用引擎借助prompt方法实现了前端代码和原生代码的交互方案。
在该方案中,应用引擎首先将要注入的Java类的公开静态方法抽取出来,根据方法名、参数类型生成相应的签名,然后将方法签名与静态的JavaScript代码组合成注入代码并将方法签名缓存起来以供和传递进来的方法进行匹配。其中静态代码的作用是将需要调用的原生代码接口以及参数信息以JSON格式封装并作为参数执行prompt方法调用,封装的信息包含标识符、类名、方法名以及参数。最后,应用引擎通过loadUrl方法将注入代码注入到Web页面中。应用引擎选择在onProgressChanged函数中当页面加载到30%时注入代码,此时注入效果最佳,既不会因为过早导致注入失败,又不会使得完成时间过晚而满足不了在页面初始化时调用原生代码接口的需求。这样,当需要在前端调用原生代码接口时,可以直接调用注入的JavaScript方法并传入参数,这些JavaScript方法会执行prompt调用。原生代码中对prompt调用进行响应的 onJsPrompt方法将会对传递进来的信息进行解析,通过标识符判断这是Web代码在调用原生代码接口并将解析得到的类名、方法名和参数与缓存的方法签名进行匹配,匹配成功则利用反射机制调用相应的原生方法,最后通过prompt返回执行结果。
应用引擎的云模块会收集移动应用的用户特性及使用数据并上传到云平台。云平台的业务模块会对这些使用数据进行统计分析,最终向开发人员提供有利于改善移动应用的分析信息。
1.2.1 数据收集
云模块收集的用户数据包括移动终端的详细信息,移动应用的启动时间、使用时长、地理位置、资源占用情况以及界面转换序列。这些数据都是以日志的形式上传到云平台的,可以分为应用使用日志和终端信息日志。
应用使用日志的字段是:时间戳、用户 ID、应用 ID、地理位置、日志类型代码、具体日志内容。用户 ID和应用ID分别是用户和移动应用的标识符。日志类型有五种:启动日志、使用时长日志、资源占用日志、界面转换日志、自定义内容日志。
终端信息日志的字段是:时间戳、用户 ID、应用 ID、日志类型代码、具体日志内容。日志类型有两种:设备信息日志、已安装应用日志。
1.2.2 数据分析
云平台接收到用户数据后会将其存入分布式存储系统,业务模块每天会对这些日志进行批处理。对日志数据的处理分析分为两部分:对除界面转换序列之外的数据使用MapReduce进行统计分析;基于状态机对应用的界面转换序列进行建模分析。
对除界面转换序列之外的数据进行统计分析后可以得到以下的数据:
(1)移动应用的用户统计,包括新增用户数、活跃用户数、僵尸用户数以及按使用时间、使用次数、地区分布的用户数。
(2)移动应用的使用情况统计,包括应用每天或每次的平均使用时长、按时间分布的使用次数。
(3)移动应用的终端特征统计,包括移动设备的型号占比、安装最多的其他应用等。
(4)移动应用的资源占用情况,包括每个版本的移动应用运行时的CPU和内存的平均占用量。
基于状态机对界面转换序列建模分析是基于Ktail算法[4]实现的,可以得到用户使用应用的界面跳转热点路径。
Ktail算法是一个根据事件序列构建事件间相互转换的有限状态机的算法,其会从事件序列中逐一读入事件,将具有相同的长度为 K的尾部的前缀构造为一个等价类作为限状态机中的一个状态,读入的事件使状态机在不同状态间转换。云平台的业务模块使用Ktail算法选择K=2将界面转换序列构建成一个自动状态机,然后将其转换成以界面为节点的状态机,最后计算界面间转换的概率生成界面跳转图。界面跳转图表示了界面之间的转换关系以及从一个界面跳转到另一个的概率。
我们可以根据界面跳转图生成应用的界面跳转热点路径。具体做法是从应用的某个界面节点开始计算长度为K的路径,在每次跳转时都选择概率最大的路径,最后,得到的路径就是热点路径。对应用的所有界面转换序列生成的热点路径进行统计就可以得到该应用从不同界面开始的不同长度的热点路径。界面热点路径描述了用户在使用应用时最常执行的界面顺序。
下文借助一个应用实例来展示分析的过程,描述了测试应用的界面情况,如表1所示:
表1 测试应用的界面
界面转换序列:ABCADABA,如图2所示:
图2 界面跳转图
如果目前应用的界面转换序列只有一个,根据图3就可获得该应用的界面跳转热点路径。从界面A开始长度为2的热点路径为 AB,由此可知用户在主界面选择概率最大的界面就是照相界面,有助于对应用的交互流程进行优化。
上文已经实现了面向智能移动终端的应用引擎,但是开发人员在基于其进行移动应用开发之前,还是需要先下载SDK并配置好开发环境,然后将应用引擎插件添加进去。因此,为了方便基于应用引擎的应用开发,应用引擎系统提供了IDE,如图3所示:
图3 IDE架构设计图
从图3我们可以看到,IDE可以分成7个部分:
(1)平台SDK模块:该模块主要提供应用开发过程中所需的平台SDK,为移动应用的编译打包、模拟运行提供必要的环境支持。
(2)项目管理模块:该模块主要负责IDE中项目的新建、删除等操作。
(3)代码编辑器模块:该模块除了提供正常的代码编辑功能之外,还提供了搜索、高亮显示以及关键词自动补全等功能。
(4)可视化开发模块:该模块提供了可视化布局和实时预览功能。
(5)编译器模块:该模块负责移动应用的编译打包,并返回编译结果。如果本机上没有配置好编译环境,该模块会将代码编译请求发送到云模块并等待编译结果。
(6)云模块:云模块主要提供云编译功能和用户操作习惯反馈功能。云编译利用云平台部署的编译环境提供在线的编译服务。用户操作习惯反馈会收集开发人员的使用习惯上传到云平台,这样云平台上的业务模块就可以对这些数据进行整理分析,生成相应的报告来指导应用引擎的优化工作。
(7)模拟器模块:模拟器提供和真实智能移动设备相似的运行环境,开发人员可以在编译好移动应用后将其上传到模拟器上运行。
接下来本文将详细介绍关键的可视化开发功能的设计和实现。
可视化开发提供了图形化的开发方式,其功能可以分为可视化布局和实时预览。可视化布局可以帮助开发人员在搭建应用的界面框架时不需要编写CSS代码,只需在可视化布局界面中拖动各控件,极大地提升了开发效率。实时预览功能可以让开发人员在编译并模拟运行应用之前预览应用的实际效果。
可视化开发模块包含3个部分。其中,代码转换器和图形编辑器实现了可视化布局功能,而页面显示则实现了实时预览功能,如图4所示:
图4 可视化开发模块架构设计图
图形编辑器是实现可视化布局的核心模块。开发人员能够通过编辑器的绘图板对应用界面进行设计,添加新控件并调整控件的大小及位置。代码转换器负责绘图板布局数据到网页布局之间的转换。根据移动应用的页面布局比较有规律的特点,IDE设计了这样的转换规则:绘图板上的控件都是以相对左上角的像素距离来定位,并且默认有长宽像素值。在转换成HTML和CSS代码时,代码转换器会将页面上除固定定位的页眉和页脚控件外的部分在纵向上分块,空白区域和每行的控件都使用div包装并以文档流的方式在页面中纵向排列,而在div块中的控件以绝对定位的方式相对于左边缘进行定位。同时,可视化开发模块还会在页面中设置viewport的target-densitydpi为 device-dpi,以解决移动设备的像素密度不同造成的页面缩放问题。此外,IDE的可视化布局会为不同的分辨率生成不同的 CSS文件以更好地适配不同尺寸的移动设备。
页面显示模块是一个基于QtWebKit内核的小型浏览器,可加载混合式应用的Web前端部分,能够实现除了平台功能、数据收集功能以及设备互联功能之外的功能交互。
本测试以一个移动应用开发实例来对应用引擎系统的功能性进行测试。
使用IDE开发移动应用的主界面,如图5所示:
图5 IDE的基本界面
IDE的上方是菜单和按钮,左侧是应用项目的树形结构列表,右侧上方主体是代码编辑器,右侧下方则是日志输出区。
应用开发中的可视化开发功能,如图6所示:
图6 可视化布局功能图
从图6可以看出可视化布局能够让开发人员通过在绘图板上添加并修改控件就能完成应用的界面设计。
可视化开发中实时预览的功能,可以在编译应用前提供实际效果的预览。由此可见可视化开发确实能够提高开发效率,降低开发难度,如图7所示:
图7 实时预览功能图
在完成应用的主界面设计之后,我们继续添加其他一些HTML页面和相应的JavaScript文件,并在JavaScript文件中设置了交互逻辑,最后编译打包应用并上传到模拟器中模拟运行。
在模拟器中运行的应用,如图8所示:
图8 在Web页面调用相册功能演示图
该页面通过应用引擎封装的JavaScript接口调用了平台功能模块的功能接口实现了从相册选取相片的功能。由此可见应用引擎的API封装模块的确可以将原生的代码接口注入到Web页面中。
应用在真实移动设备上的运行效果,如图9所示:
图9 移动应用在真实设备上运行图
此时移动应用通用应用引擎的设备互联模块与智能设备实现了画面共享。
混合式应用和原生应用的最主要的差别是混合式应用是在Web页面中通过JavaScript调用系统的功能接口的,调用效率和应用引擎的API封装机制有很大的关系。因此,本测试对应用引擎中 API封装机制的效率进行了测试。图 10是在前端通过API封装机制调用与在原生代码中直接调用简单测试函数所用时间的对比图,如图10所示:
图10 在前端和原生代码中调用测试函数时间对比图
测试函数只包含return语句,因此,可以忽略其执行时间,把测得的时间作为调用过程所花的时间。
从图 10可以看出,在原生代码中直接调用函数所花的时间几乎可以忽略,而使用应用引擎的API封装机制在Web页面调用原生代码接口所花的时间相对较长,不过其所花时间的数量级依然在可接受范围内。并且,这可能与JavaScript执行循环的效率不如原生代码有很大的关系。
针对目前移动应用开发过程中的种种问题,本文提出并实现了一种面向移动应用开发的应用引擎以及相应的 IDE。应用引擎从实际需求出发,给出了API封装、数据收集等功能的解决方案。IDE设计并实现了可视化开发、模拟器运行等功能。使用基于应用引擎的IDE,开发人员只需编写前端代码就可开发移动应用,并且能够快速地搭建应用界面架构,降低了移动应用的开发门槛,提高了开发效率。
[1] Serrano, N, Hernantes, J, Gallardo, G. Mobile Web Apps[J]. Software, IEEE, 2013, 30(5): 22-27.
[2] Parag Gokhale, Sachchidanand Singh. Multi-platform Strategies, Approaches and Challenges for developing Mobile applications[C]. Mumbai: IEEE, 2014: 289-293.
[3] libers. WebView中接口隐患与手机挂马利用[EB/OL].http://drops.wooyun.org/papers/548, 2013-09-04.
[4] Jonathan E. Cook, Alexander L. Wolf. Discovering Models of Software Processes from Event-Based Data[J].ACM Transactions on Software Engineering and Methodology, 1998, 7(3):215-249.