赞
踩
Cordova是PhoneGap贡献给Apache后的开源项目,是从 PhoneGap中抽离出的核心代码,是驱动PhoneGap的核心引擎。有点类似Webkit和Google Chrome的关系。渊源就是:早在2011年10月,Adobe收购了Nitobi Software和它的PhoneGap产品,然后宣布这个移动Web开发框架将会继续开源,并把它提交到Apache Incubator,以便完全接受ASF的管治。当然,由于Adobe拥有了PhoneGap商标,所以开源组织的这个PhoneGap v2.0版产品就更名为Apache Cordova。
Apache Cordova是一个开源的移动开发框架,它支持使用标准的Web开发技术(HTML5、CSS3和JavaScript)开发跨平台的移动端应用。如果需要访问各平台本地化的功能,如摄像头、网络、传感器……,可以通过使用插件(plugin)来完成。
cordova架构示意图如下:
Web App层是开发人员编写代码的主要地方,应用程序以网页的形式呈现,在一个index.html的本地页面文件中引用所需要的各种Web资源,如CSS、JavaScript、图像、影音文件等。应用程序的配置保存在config.xml文件中。
WebView层用来呈现用户界面,即web页面的展现。例如,在android平台是通过WebView控件实现web页面的呈现。
Plugins主要用于在JavaScript代码中调用各平台native的功能。Cordova项目已经包含一些核心的plugin,如电池、摄像头、通讯录等。开发人员也可以开发自定义的plugin,来实现所需要的功能。
Cordova预先帮我们预先封装了各种mobile os上最常用的本地api调用,然后以统一的Javascript api形式提供给webapp开发者调用。(注:cordova还提供另外一种Hybird即混合开发模式,这个后面有时间再说。)对于webapp的开发者来说,无需关注系统底层调用实现细节,也就实现了所谓的“跨平台”。实际上,各平台涉及到本地能力的调用,以插件形式被封装了。(每个插件的实现实际上还是Native模式)。
笔者比较感兴趣的一点是JS和Native是如何实现互调的(各平台有差别,这里先研究Android的,重点是JS如何实现对于Native的调用),网上实际上有比较多的文章在解释这些,看下来感觉总不是太清晰,于是乎,你懂的,我直接对着github上Cordova-Android源码来了一番研究。
先把研究的结果共享出来:Cordova-Android是通过addJavascriptInterface(Android Webview的API)和JS Prompt这两种方式来实现JS对于Native API的调用。
具体介绍这两种方式前,我们先来看一个Cordova-Android框架中的一个关键类:CordovaActivity.java。
该类继承了Android Activty类,实际上是Cordova-Android的Launcher Activity,也就是启动入口activity。我们通过一张图来描述下它干了哪些事:
应用启动后,核心干了两件事:读取config.xml和loadUrl。这个loadUrl实际上就是加载webapp的启动页(默认是index.html)。
addJavascriptInterface方式:
看了上面的图,再看下其中的一个核心类的代码,就啥都明白啦。
SystemExposedJsApi.java
我们直接看代码,很短:
- /*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
- */
- package org.apache.cordova.engine;
-
- import android.webkit.JavascriptInterface;
-
- import org.apache.cordova.CordovaBridge;
- import org.apache.cordova.ExposedJsApi;
- import org.json.JSONException;
-
- /**
- * Contains APIs that the JS can call. All functions in here should also have
- * an equivalent entry in CordovaChromeClient.java, and be added to
- * cordova-js/lib/android/plugin/android/promptbasednativeapi.js
- */
- class SystemExposedJsApi implements ExposedJsApi {
- private final CordovaBridge bridge;
-
- SystemExposedJsApi(CordovaBridge bridge) {
- this.bridge = bridge;
- }
-
- @JavascriptInterface
- public String exec(int bridgeSecret, String service, String action, String callbackId, String arguments) throws JSONException, IllegalAccessException {
- return bridge.jsExec(bridgeSecret, service, action, callbackId, arguments);
- }
-
- @JavascriptInterface
- public void setNativeToJsBridgeMode(int bridgeSecret, int value) throws IllegalAccessException {
- bridge.jsSetNativeToJsBridgeMode(bridgeSecret, value);
- }
-
- @JavascriptInterface
- public String retrieveJsMessages(int bridgeSecret, boolean fromOnlineEvent) throws IllegalAccessException {
- return bridge.jsRetrieveJsMessages(bridgeSecret, fromOnlineEvent);
- }
- }

@JavascriptInterface暴露方法给JS,这里的exec接口方法实际上就实现了从JS到Native调用的“桥”。
至此,我们对于addJavscriptInterface这种方式的调用过程就搞清楚了。对于JS Prompt这种方式,原理上大同小异。实际上Cordova在SystemWebChromeClient.java这个类中重载了OnJsPrompt方法。实际的调用过程如下:webapp->prompt()->OnJsPrompt()->Native()。
分析下这个过程的反面,也就是从Native端->JS端,Cordova是如何处理的。
老习惯,我们先看一段代码:
exec.js
- nativeToJsModes = {
- // Polls for messages using the JS->Native bridge.
- POLLING: 0,
- // For LOAD_URL to be viable, it would need to have a work-around for
- // the bug where the soft-keyboard gets dismissed when a message is sent.
- LOAD_URL: 1,
- // For the ONLINE_EVENT to be viable, it would need to intercept all event
- // listeners (both through addEventListener and window.ononline) as well
- // as set the navigator property itself.
- ONLINE_EVENT: 2
- }
可以看到Cordova实现了3中模式:POLLING、LOAD_URL和ONLINE_EVENT。笔者这里重点分析了第一种,也就是POLLING模式,后两种有机会再做深入研究。下图大致描述了这个过程。
总体来说,过程如下:
1、JS端调用Native API后,如果当前调用消息未处理完成,每隔50ms取一次消息队列,直到本次调用的消息结束;
2、Native端的插件同样维护了一个消息队列;
3、JS端通过Native端暴露的retrieveMessages接口来实现消息的拉取;
另外,通过源代码我们可以大致分析下Cordova的JS和Native两端的消息格式大致协议:
1、* 号的消息表示当前Native端仍然有待处理消息,JS端会再拉取一次消息;
2、消息内容的第一个字符如果为S表示调用成功,F表示调用失败;
其他的有兴趣的可以对照代码再做分析。
工程建立并添加android平台后,可以在/platform/android/目录下找到cordove创建的android工程。
注意:android工程是临时的,cordova会覆盖该目录下的文件。工程开发主要工作是开发工程目录下的www目录、config.xml文件,以及自定义的plugin,而不是修改该android目录下的内容。
原生移动app框架inoic功能研究
本篇只侧重框架提供的功能和能力的研究,请关注后续实际部署使用体验。
一、inoic是什么?
inoic是一个可以使用Web技术以hybird方式开发移动app的前端开源框架。
二、inoic框架特点
1.利用web技术开发移动app。
ionic提供了一套HTML、CSS、JS的类库。我们可以使用其提供的CSS组件和工具构建具有良好交互性的app。
2.关注性能
ionic框架以更少的DOM操作,零JQuery和硬件加速过度,在现代最新的移动设备上性能表现优越。
3.Angular
ionic基于Angular创建了一套最合开发丰富健壮的app的强大SDK。ionic与Angular完美融合,提供了适合专业化app开发的核心架构。
4.关注原生
ionic对当下流行的原生移动开发SDKs进行抽象,并利用ApacheCordova或者Phonegap编译,使开发人员只关注自己的代码,而不用针对IOS和Android开发多套原生app。可以实现开发一次,任意部署。
5.UI设计精美
UI干净、简单、实用。其提供了流行的移动组件、结构、交互规范、漂亮的皮肤。
6.功能强大的CLI
一个命令可以完成创建、构建、测试、部署ionic app到任意平台。
7.学习有趣
只需要学习HTML、CSS、JS、AngularJS。
8.提供专业原型工具
使用Creator可以通过简单的拖拽创建真正的ionicapp。其可以导出干净、立即可用的ionic代码,甚至是IOS和Android二进制文件。网站提供了在线体验,但是可能是国内网络的原因,登录后无法进行操作。
9.提供了启动、构建、测试和部署的专业化工具Lab,但是打开页面无法进行下载。
10.提供了一个应用市场,可以上传app和插件,但是市场页面没有东西,没有活力。
三、ionic依赖的底层技术
ionic仅仅是开发hibrid移动app的前端框架,其依赖一些底层的技术框架
1.其依赖apacheCordova或者Phonegap提供的原生SDK访问能力,并依赖其将ionicapp编译部署。
2.Sass,其核心css是使用Sass编写,可以利用Sass对Css功能的增强能力,以及灵活易于维护的能力,
同时保障了ionic框架的css扩展能力。
3.Angularjs,其通过angularjs对apacheCordova提供的原生SDK接口进行封装(称为ngAngular),同时其也依赖angularjs提供的动画、触控系统、ui交互功能,同时angularjs的核心架构也是基于angularjs的MVC模式构建的。
四、浏览器兼容性
ionic重点关注原生或者hibird移动app,而不是移动web站点。其更关注特定平台提供的WebView控件的兼容性。对于1.2.4版本的ionic支持IOS7+和Android4.1+的UIWebView。
五、开源协议
基于MIT协议,可以免费用于个人和商业项目。
六、技术支撑
ionic是一个叫Drifty公司的三个人员开发的,该公司还有Codiqa和Jetstrap两个移动产品。哦盖过了
七、ionic提供的CSS组件
框架提供了丰富多样的CSS组件包括Header、Content、Footer、Buttons、List、Cards、Forms、Toggle、CheckBox、RadioButton、Grid等
八、平台相关定制
1.平台相关类
ionic提供了平台设备类和平台OS版本类以方便我们修改或者扩展现有样式。ionic会在app启动的时候在body里添加相关的平台类。
平台设备相关类如下
2.使用CSS直接自定义平台相关样式
针对android自定义bar-header的文本样式。
.platform-android .bar-header { text-transform: uppercase; }
3.
使
angular
直接自定义平台相关样式
ionic
通过
ionic.Platform
暴露平台相关类
,我们可以在控制器中获取平台类
.controller('AppCtrl', function($scope) { $scope.platform = ionic.Platform.platform(); })
我们也可以在
html
元素中使用平台类控制元素的样式
,比如控制标签在
android
的时候显示一种样式,其他系统的时候显示另外一种样式。
<ion-tabs class="tabs-stable" ng-class="{'tabs-positive': platform == 'android', 'tabs-icon-top': platform != 'android'}"> <!-- ion-tab directives go here --> </ion-tabs>
根据平台加载不同模板
.state('tab', { url: "/tab", abstract: true, controller: 'AppCtrl', templateUrl: function() { if (ionic.Platform.isAndroid()) { return "templates/home-android.html"; } return "templates/home.html"; } })
4.
使用
merge
文件夹加载不同的文件
merges/ ios/ index.html css/ platform.css js/ app.js android/ index.html css/ platform.css js/ app.js
九、JS组件
ionic提供的css组件是通过基于angular实现的control实现用户交互功能的。可以简单看下list的用法
<ion-list ng-controller="MyCtrl" show-delete="shouldShowDelete" show-reorder="shouldShowReorder" can-swipe="listCanSwipe"> <ion-item ng-repeat="item in items" class="item-thumbnail-left"> <img ng-src="{{item.img}}"> <h2>{{item.title}}</h2> <p>{{item.description}}</p> <ion-option-button class="button-positive" ng-click="share(item)"> Share </ion-option-button> <ion-option-button class="button-assertive" ng-click="edit(item)"> Edit </ion-option-button> <ion-delete-button class="ion-minus-circled" ng-click="items.splice($index, 1)"> </ion-delete-button> <ion-reorder-button class="ion-navicon" on-reorder="reorderItem(item, $fromIndex, $toIndex)"> </ion-reorder-button> </ion-item> </ion-list>
app.controller('MyCtrl', function($scope) { $scope.shouldShowDelete = false; $scope.shouldShowReorder = false; $scope.listCanSwipe = true });
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。