Jerry之前的一篇文章 SAP Fiori应用的三种部署方式 曾经提到SAP Fiori应用的三种部署方式:
On Premise环境下以ABAP BSP应用作为Fiori应用部署和运行的载体
部署并运行在On Cloud环境下,比如SAP云平台
用Cordova打包成平台原生应用安装在移动设备上
今天这篇文章我们就来专门聊聊第三种方式,也就是SAP移动应用的解决方案之一: 使用Cordova将前端应用打包成一个和移动平台相关的混合移动应用。
本文首先由Jerry向大家对Cordova做一个总体介绍,然后由Jerry的同事,SAP成都研究院Cloud for Customer开发团队的Yang Joey(他的背景介绍可以在这篇文章SAP成都研究院C4C光明左使:SAP Cloud for Customer使用SAP UI5的独特之处找到)向大家介绍Cordova是如何应用在SAP C4C移动应用里的。
除了Cordova外,业界还有很多其他的移动开发框架,比如Facebook的React Native,虽然据我所知SAP的标准产品没有用到它,但我从我的同事,拥有“集产品经理,开发人员和架构师三者于一身”称号的彭宇飞那里了解到,SAP很多客户定制化开发项目也使用到了React Native。除此之外还有阿里的Weex,Angular Mobile UI等框架,这些Jerry都没有用过,不在本文讨论范畴内。
按照传统的移动开发方式,iOS和Android开发人员需要学习和移动平台相关的编程语言和编程环境,在平台A上开发的代码完全不可能直接应用到另一个平台B去。比如SAP曾经发布过一款基于iOS的原生移动应用,SAP Customer Briefing。2011年时,Jerry所在的开发小组接到任务,需要把这款应用移植到Android平台。Jerry和开发小组的其他三位同事,一边啃着iOS版Object C的源码来理解该应用的逻辑,一边用Java全部重写,历经整整7个月的时间才完成移植。
另一方面,一个不具备移动应用开发知识的Web开发人员,在Cordova的帮助下,也能打造出能够直接安装到移动设备上的移动应用。这种应用的用户体验,和用原生编程工具(比如XCode和Android Studio)和编程语言开发出的应用几乎没有差别。为了区分,有时候我们将用Cordova加上Web应用生成的移动应用称为混合应用(Hybrid App)。
Cordova的神奇之处在哪里?
学习Cordova,最好的渠道莫过于其官网,上面有详细的从入门到进阶的文档。
https://cordova.apache.org/docs/en/latest/
Cordova是一个开源的移动开发框架,允许开发人员用标准的Web技术,即HTML5,CSS3和JavaScript完成跨平台的移动应用开发。所谓跨平台,即类似Java的“一次编译,到处执行”,我们只需要专注于前端应用的开发,完毕之后,根据实际需要,再使用Cordova提供的build工具,将开发好的前端应用打包成能够安装到移动平台上去的混合应用。
下图是Cordova官网上的架构图。其中橘色的Cordova Application即前端应用使用Cordova工具打包后的混合应用。在运行时,这个混合应用里的前端资源被加载,渲染,运行在一个嵌入的WebView控件里。这个嵌入的WebView通过Cordova框架提供的插件(Plugins)访问移动操作系统的核心功能,比如相机,存储等系统调用。如果您的混合应用里需要使用的某些移动操作系统提供的API,Cordova现有插件无法支持,您还有另一种方式可以选择:直接在移动开发平台上开发您自己的Cordova插件(即下图蓝色的Custom Plugins),在该插件里调用移动操作系统的API,然后通过JavaScript接口暴露给您的前端应用消费。
SAP Cloud for Customer和SAP Mobile Platform解决方案里包含了很多SAP开发的Cordova插件。其中C4C的Cordova插件将由Joey在下文做介绍,而SMP的Cordova插件集合,SAP称之为Kapsel Plugins:
https://help.sap.com/saphelp_smp305sdk/helpdata/en/5e/ace0a880431014b0d1a04ab6335d4e/frameset.htm
以前做Fiori开发时,Jerry曾经对Kapsel插件里的OData Offline插件的工作原理非常好奇。因为我是Android手机的死忠粉丝,所以仔细研究过Offline插件在Android平台上的源码和工作原理:
How is OData request routed to Offline data store by Odata offline plugin
https://blogs.sap.com/2016/08/04/how-is-odata-request-routed-to-offline-data-store-by-odata-offline-plugin/
How is JavaScript code in OData offline plugin delegated to native Java code in Android
https://blogs.sap.com/2016/08/04/how-is-javascript-code-in-odata-offline-plugin-delegated-to-native-java-code-in-android/
How is OData offline store opened in Android platform
https://blogs.sap.com/2016/08/05/how-is-odata-offline-store-opened-in-android-platform/
Talk is cheap, show me the code. 现在我们来看看将一个Fiori应用用Cordova打包成混合应用的具体步骤。这个混合应用最后运行在我的三星手机上的界面如下图所示:
命令行npm -g install cordova安装Cordova:
命令行cordova create新建一个Cordova项目:
这个命令行已经帮助我们自动生成了很多稍后打包成混合应用所必需的资源文件。
假设我想生成基于Android平台的混合应用,那么用命令行添加对Android平台的支持:
cordova platform add android
现在在Cordova项目下platforms文件夹里,会多出一个android文件夹,里面包含的是运行于Android平台的混合应用所必需的资源。
把你的Fiori应用的整个项目全部拷贝到Cordova项目文件夹下的www目录内。执行命令行cordova prepare,www目录内的所有Fiori应用的资源文件会自动被拷贝到文件夹platformsandroidassetswww下面。
最后执行命令cordova compile,生成可以安装到Android设备上的apk文件。
整个过程就是这样。总结一下,Fiori应用开发好之后,只需四个命令行,就能把该Fiori应用打包成一个能在Android平台上运行的混合应用,确实体现了Cordova降低移动开发成本和提高跨平台开发效率的优势。
cordova create
cordova platform add android
cordova prepare
cordova compile
如果要在某移动平台上开发一个新的Cordova插件,步骤也很简单。
我用Java实现一个加法器,用来模拟Android平台提供的API,然后用JavaScript暴露给前端应用。
命令行创建一个名称为Adder,id为jerry.adder的插件:
plugman create -name Adder -plugin_id jerry.adder -plugin_version 1.0.0
创建完毕后,会生成一个同名文件夹Adder:
用命令行声明这个插件是为Android平台服务的:
plugman platform add –platform_name android
这个命令会自动生成一个Adder.java。下一步就是Java编程。JavaScript端传入的两个操作数通过输入参数args获得,在Java端执行加法,结果再通过CallbackContext传回给JavaScript端,后者通过一个回调函数获取Java端的加法计算结果。
Java开发结束后,通过下面的命令行将插件添加到混合应用中,再使用cordova compile就能得到最新的包含了这个自定义插件的apk。
cordova plugin add Adder
在前端JavaScript代码里,使用Cordova提供的接口,Cordova.exec来消费插件,见下图第15行,执行加法的两个操作数10和20通过数组传入。
这个加法在Java端执行,通过回调函数返回给前端,通过第11行的alert打印出来:
详细步骤参考我的博客:
https://blogs.sap.com/2017/08/18/step-by-step-to-create-a-custom-cordova-plugin-for-android-and-consume-it-in-your-ui5-application/
这个Android插件当然是可以调试的,用Android Studio即可。详细的环境配置和调试方法,参考我的博客:
https://blogs.sap.com/2017/08/18/how-to-debug-ui5-application-packaged-into-a-mobile-device-via-cordova-with-a-custom-plugin/
基于Cordova的SAP Cloud for Customer移动解决方案 - Yang Joey
大家好,我是Joey。SAP Cloud for Customer的移动解决方案,我们内部简称为Aurora。Aurora就是张韶涵的专辑《欧若拉》里提到的,北欧神话中掌管黎明和曙光的女神。
很有意思的是,SAP C4C美国开发团队的同事们,以程序员特有的幽默感,在我们C4C本地开发环境的启动脚本里,加入了在控制台里输出Aurora女神的逻辑,让我们每一位C4C开发人员每天都会一睹这位女神的尊容。给这些有情怀的同事们点赞!
我2017年夏天加入SAP成都研究院C4C开发团队时,非常好奇我每天工作中写的Javascript代码是如何运行在移动设备上的。于是,以Android平台为例,我把SAP发布到Android应用市场的应用解压出来研究了一下。
我将从Android应用市场下载下来的apk文件后缀名改成zip,然后解压缩。得到如下的文件夹,这是一个经典的Android应用apk包的结构:
前面Jerry已经介绍过,用Cordova工具将C4C项目文件打包成Android混合应用后,客户安装apk在Android设备上后,该混合应用实际上运行于Android平台的WebView中。
WebView里加载的JavaScript和HTML文件来自于Cordova compile命令行构建出来的apk文件里。运行时,这些资源文件通过apk内一个嵌入的Web服务器加载到WebView里。
当然,C4C移动应用上需要显示的C4C业务数据,比如在手机上的C4C应用里打开Account工作中心,看到的所有Account数据都来自对应的C4C后台系统。这些数据的读取请求通过apk内部的嵌入Web服务器发送到C4C后台 ABAP系统上去。
我们打开apk解压而成的文件夹下面的子文件夹assets/www, 看到如下这些文件结构:
其中最醒目的是好几个zip包:
cod.zip
oberon.zip
oberon.ui5.zip
这几个zip即是整个C4C前端实现的完整代码,包含JavaScript代码和CSS样式表文件。我们可以打开oberon.zip看看里面的具体内容。
下图左边是登录某个C4C系统后在Chrome开发者工具的Sources标签页里观察到的加载的JavaScript文件,右边是混合应用的apk文件里包含的oberon.zip里的内容。
做过Fiori应用的朋友们还记得,Fiori应用的入口,如果是配置到Fiori Launchpad作为一个Tile来访问,那么入口就是Component.js, 否则作为一个standalone的应用,入口是包含了sap-ui-core.js的网页,通常是index.html。
C4C应用的入口是后者,让我们看看index.html的内容:
可以看到index.html加载了两个js文件,运行了app.initialize()方法,该方法被定义在加载的第二个js文件js/index.js里面,打开这个index.js文件之后发现的确是该initialize 方法加载了SAP的UI标准库,主题库,语言等:第27行的sap-ui-core.js就是我们的老朋友了。
而loadOberon和前面多次提及的oberon.zip, 这个oberon是什么意思?实际就是SAP C4C的UI框架名称,该框架包含了使用UI Designer开发的XML View,后台存储这些View的XRepository,以及渲染这些View的JavaScript代码等等。整套框架在我之前的文章 SAP成都研究院C4C光明左使:SAP Cloud for Customer 使用SAP UI5的独特之处 里也有介绍。
Jerry之前以Java端的加法器为例,介绍了如何开发一个新的Cordova插件。Jerry也提到了SAP Mobile Platform里开发的Cordova插件的集合称为Kapsel。同样,在C4C基于Android平台的apk文件解压出来的文件夹中,我们也能发现很多SAP C4C Cordova插件:
这些文件夹里存放的都是C4C 在Android平台的Cordova插件对应的JavaScript接口。C4C移动正是通过这些JavaScript接口来消费用Java开发的Cordova插件。
随便打开一个文件夹com.sap.byd.cod.businessCardScanner里的JavaScript文件,从下图第13行能看出,同之前Jerry在他的测试前端应用里消费自开发的Java加法器插件一样,用JavaScript消费Java插件的方法仍然是调用Cordova框架提供的方法cordova.exec,第三个参数BusinessCardScanner即对应插件实现的Java类名称,scan即这个Java类的一个public方法名称,用于实现插件的业务逻辑。
要获取更多Jerry的原创技术文章,请关注公众号"汪子熙"
联系客服