文档章节

浅谈Cordova框架的一些理解

o
 osc_nyhmdnf9
发布于 2018/07/06 11:14
字数 3218
阅读 7
收藏 0

行业解决方案、产品招募中!想赚钱就来传!>>>

浅谈Cordova框架的一些理解

一、总结

一句话总结:cordova是让你用web技术-HTML5,CSS3和JavaScript做做移动端开发(包括Android,ios)。而且是跨平台。

 

1、cordova是做什么的?

Apache Cordova是一个开源的移动开发框架。允许你用标准的web技术-HTML5,CSS3和JavaScript做跨平台开发。 应用在每个平台的具体执行被封装了起来,并依靠符合标准的API绑定去访问每个设备的功能,比如说:传感器、数据、网络状态等。

 

2、和coedova相同功能的另外一个常用框架叫什么名字?

cloud

 

3、Cordova可以访问设备的功能比如传感器,地理位置么

应用在每个平台的具体执行被封装了起来,并依靠符合标准的API绑定去访问每个设备的功能,比如说:传感器、数据、网络状态等。

 

 

二、浅谈Cordova框架的一些理解

前言

因为工作原因,最近需要研究Cordova框架,看了其中的源码和实现方式,当场在看的时候马上能理解,但是事后再回去看相关源码时候却发现之前理解的内容又忘记了,又不得不重新开始看,所以总觉得需要记录下来,这样也表明之前也是学习过,俗话说「好记性不如烂笔头 」,想必也是体现了笔记的重要性。

目录

  • 为何要用Cordova

  • 什么是Cordova

  • Cordova中UML类图

  • Cordova实现机制

  • 小结

为何要用Cordova

随着移动互联网的发展,现在基本是APP满天飞,不知在大家印象中,如果我去下载一个APP,那么基本都能看到有两种选择,一种是Android版本,一种是IOS版本。不管我的手机是哪种操作系统,安装完一个APP之后,后续如果有新的版本发布的时候,我还必须去更新,才能享用新版本里的功能,比如我装了“京东”这个APP,前几天正好碰到“618”活动,那么之前一个月APP Store就提醒我要去更新最新的APP版本,以免错过“618”活动中新的功能使用。相对来说IOS系统更新APP比起Android系统用户体验会好一点,但是还是稍显麻烦点。

那么有没有一种方式,我只需要开发一个APP版本,就能去适配通用的操作系统呢,不仅可以适配Android、IOS,还可以适配其他系统,比如Windows Phone、 Palm WebOS、Blackberry等等。有,Cordova就能提供这种能力,代码写一次,就能到处运行,跟我们日常开发网站效果一样,基于写Web APP,根据输出平台要求不同,就能提供不同类型的安装包。Cordova其设计初衷是希望用户群体能够通过跨平台开发的方法降低原生开发的成本,为此,开发人员需要安装原生开发环境,配置工程,使用HTML5CSS3JS和原生SDK生成应用。

什么是Cordova

官网定义如下:

Apache Cordova是一个开源的移动开发框架。允许你用标准的web技术-HTML5,CSS3和JavaScript做跨平台开发。 应用在每个平台的具体执行被封装了起来,并依靠符合标准的API绑定去访问每个设备的功能,比如说:传感器、数据、网络状态等。

使用Apache Cordova的人群:

  • 移动应用开发者,想扩展一个应用的使用平台,而不通过每个平台的语言和工具集重新实现。

  • web开发者,想包装部署自己的web App将其分发到各个应用商店门户。

  • 移动应用开发者,有兴趣混合原生应用组建和一个WebView(一个特别的浏览器窗口) 可以接触设备A级PI,或者你想开发一个原生和WebView组件之间的插件接口。

架构图

框架图

从图中,我们可以看到它提供了Web APP、WebView、Cordova Plugins。

Web APP

这是存放应用程序代码的地方,体现是你的具体业务逻辑模块。应用的实现是通过web页面,默认的本地文件名称是是index.html,这个本地文件应用CSS,JavaScript,图片,媒体文件和其他运行需要的资源。应用执行在原生应用包装的WebView中,这个原生应用是你分发到app stores中的。

WebView

Cordova启用的WebView可以给应用提供完整用户访问界面。在一些平台中,他也可以作为一个组件给大的、混合应用,这些应用混合和Webview和原生的应用组件。

Cordova Plugins

插件是Cordova生态系统的重要组成部分。他提供了Cordova和原生组件相互通信的接口并绑定到了标准的设备API上,这使你能够通过JavaScript调用原生代码。

Cordova中UML类图

其实Cordova通过命令来添加项目的,但是可以选择哪个平台去编译,比如我们添加Android平台,在Android默认mainActivity类,我们可以看到它其实继承CordovaActivity类,一切初始化条件是从loadUrl方法开始。

package com.example.hello;

import android.os.Bundle;
import org.apache.cordova.*;

public class MainActivity extends CordovaActivity
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        // enable Cordova apps to be started in the background
        Bundle extras = getIntent().getExtras();
        if (extras != null && extras.getBoolean("cdvStartInBackground", false)) {
            moveTaskToBack(true);
        }

        // Set by <content src="index.html" /> in config.xml
        loadUrl(launchUrl);
    }
}

进而得到以下UML类图

UML图

简单分析下,CordovaActivity内依赖一个WebView类,一个Preferences类,一个CordovaInterface接口,并同时初始化一些配置信息。WebView具体实现是由CordovaWebViewImpl类,CordovaInterface接口具体实现是由CordovaInterfaceImpl类实现。

CordovaWebViewImpl是核心类,里面会把一些插件能力初始化,用一个PluginManager进行管理,包含一个引擎类—CordovaWebViewEngine,这个引擎是通过反射的方式创建,自身初始化的时候把NativeToJsMessageQueue关联起来,里面包含着以Js字符串为主的双向链表,把每次从前端通过JS代码存储起来,然后通过绑定的桥接方式Pop出到相应的Native代码中去。

最终实现由SystemWebViewEngine类来对Android系统中WebView控件进行二次包装,这个类的初始化是在CordovaWebViewImpl类反射创建,相关插件和消息传递也是通过SystemWebViewEngine进行绑定。

Cordova实现机制

当Cordova框架启动时候,CordovaActivity类中的onCreate方法调用loadUrl方法即可启动,最终在SystemWebViewEngine类的init方法中,会调用webView的addJavascriptInterface方法,看到这个方法是不是很熟悉,我们常规让webView支持开启JavaScript调用接口也是使用此特性。

 private static void exposeJsInterface(WebView webView, CordovaBridge bridge) {
        if ((Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1)) {
            LOG.i(TAG, "Disabled addJavascriptInterface() bridge since Android version is old.");
            // Bug being that Java Strings do not get converted to JS strings automatically.
            // This isn't hard to work-around on the JS side, but it's easier to just
            // use the prompt bridge instead.
            return;
        }
        SystemExposedJsApi exposedJsApi = new SystemExposedJsApi(bridge);
        webView.addJavascriptInterface(exposedJsApi, "_cordovaNative");
    }

那么SystemExposedJsApi类new出来的对象就等同抛出“_cordovaNative”对象给JS端调用,进去看下SystemExposedJsApi类包含哪些内容,

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);
    }
}

其中最关键是exec方法,其中bridgeSecret代表选择哪个桥接方式,service一般对应着你本地Java文件类名,action代表java文件中方法名,callbackId代表回调函数的Id,也就是句柄,arguments代表传递的参数。看出其中设计思想了没,service往往是本地能力集的类名,比如web端想调用相机,一般起个Camera类代表这个相机服务类,然后在这个类中定义方法,也就是action参数,这个action名称可扩展,因为方法名称可各种各样,适合自定义功能扩展。

SystemExposedJsApi对象初始化

在创建SystemExposedJsApi时需要CordovaBridge类,CordovaBridge类初始化需要CordovaWebView的PluginManager对象和NativeToJsMessageQueue对象。因为所有的JS端与Android native代码交互都是通过SystemExposedJsApi对象的exec方法。在exec方法中执行PluginManager的exec方法,PluginManager去查找具体的Plugin并实例化然后再执行Plugin的execute方法,并根据同步标识判断是同步返回给JS消息还是异步。由NativeToJsMessageQueue统一管理返回给JS的消息。

何时加载Plugin,如何加载

Cordova中很重要的部分是插件,Cordova在启动每个Activity的时候都会将配置文件中的所有plugin加载到PluginManager,在第一次loadUrl方法时,就会去初始化PluginManager并加载plugin,PluginManager在加载plugin的时候并不是马上实例化plugin对象,而是只是将plugin的Class名字保存到一个hashmap中,用service名字作为key值。当JS端通过JavascriptInterface接口的SystemExposedJsApi对象请求Android时,PluginManager会从hashmap中查找到plugin,如果该plugin还未实例化,利用java反射机制实例化该plugin,并执行plugin的execute方法。

Cordova的数据返回

Cordova中通过exec()函数请求android插件,数据的返回可同步也可以异步于exec()函数的请求。在开发android插件的时候可以重写public boolean isSynch(String action)方法来决定是同步还是异步。Cordova在android端使用了一个队列(NativeToJsMessageQueue)来专门管理返回给JS的数据。

1,同步
Cordova在执行完exec()后,android会马上返回数据,但不一定就是该次请求的数据,可能是前面某次请求的数据;因为当exec()请求的插件是允许同步返回数据的情况下,Cordova也是从NativeToJsMessageQueue队列头pop头数据并返回。然后再根据callbackID反向查找某个JS请求,并将数据返回给该请求的success函数。
2,异步
Cordova在执行完exec()后并不会同步得到一个返回数据。Cordova在执行exec()的同时启动了一个XMLHttpRequest对象方式或者prompt()函数方式的循环函数来不停的去获取NativeToJsMessageQueue队列中的数据,并根据callbackID反向查找到相对应的JS请求,并将该数据交给success函数。

webView.sendJavascript 发送到js队列,onNativeToJsMessageAvailable 负责执行js.

Native 调用 JS 执行方式有三种实现 LoadUrlBridgeMode、 OnlineEventsBridgeMode、PrivateApiBridgeMode

1、webView.sendJavascript 发送js方法到JS队列

2、onJsPrompt 方法拦截,获取调用方式

  • 如果是gap_bridge_mode,则执行 appView.exposedJsApi.setNativeToJsBridgeMode(Integer.parseInt(message));
  • 如果是gap_poll, 则执行 appView.exposedJsApi.retrieveJsMessages("1".equals(message));

3、调用setBridgeMode 方法调用onNativeToJsMessageAvailable 执行javascript调用

小结

总的来说,使用Cordova框架开发优缺点很明显。

优点:

  • 跨平台,开发简单,学习成本低
  • 框架多,插件多,可自定义插件
  • 发展最早,社区资源丰富,

缺点:

  • WebView性能低下时,用户体验差,反应慢
  • 毕竟是老外的框架,中文文档资源少
  • 调试不方便,既不像原生那么好调试,也不像纯web那种调试

最后想说一句,无论是选择原生模式开发还是Hybrid混合模式,一定是要基于具体业务场景去选择,而不是盲目和绝对化觉得哪种模式好就不做分析想当然的去选择,还是有选择的结合,要知道应用之美在于药到病除。

阅读扩展

源于对掌握的Android开发基础点进行整理,罗列下已经总结的文章,从中可以看到技术积累的过程。
1,Android系统简介
2,ProGuard代码混淆
3,讲讲Handler+Looper+MessageQueue关系
4,Android图片加载库理解
5,谈谈Android运行时权限理解
6,EventBus初理解
7,Android 常见工具类
8,对于Fragment的一些理解
9,Android 四大组件之 " Activity "
10,Android 四大组件之" Service "
11,Android 四大组件之“ BroadcastReceiver "
12,Android 四大组件之" ContentProvider "
13,讲讲 Android 事件拦截机制
14,Android 动画的理解
15,Android 生命周期和启动模式
16,Android IPC 机制
17,View 的事件体系
18,View 的工作原理
19,理解 Window 和 WindowManager
20,Activity 启动过程分析
21,Service 启动过程分析
22,Android 性能优化
23,Android 消息机制
24,Android Bitmap相关
25,Android 线程和线程池
26,Android 中的 Drawable 和动画
27,RecylerView 中的装饰者模式
28,Android 触摸事件机制
29,Android 事件机制应用
30,Cordova 框架的一些理解
31,有关 Android 插件化思考
32,开发人员必备技能——单元测试

 
参考:
浅谈Cordova框架的一些理解 - cryAllen - 博客园
https://www.cnblogs.com/cr330326/p/7082821.html
 
 
o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。
Netty那点事(三)Channel与Pipeline

Channel是理解和使用Netty的核心。Channel的涉及内容较多,这里我使用由浅入深的介绍方法。在这篇文章中,我们主要介绍Channel部分中Pipeline实现机制。为了避免枯燥,借用一下《盗梦空间》的...

黄亿华
2013/11/24
2W
22
beego API开发以及自动化文档

beego API开发以及自动化文档 beego1.3版本已经在上个星期发布了,但是还是有很多人不了解如何来进行开发,也是在一步一步的测试中开发,期间QQ群里面很多人都问我如何开发,我的业余时间实在...

astaxie
2014/06/25
2.7W
22
5分钟 maven3 快速入门指南

前提条件 你首先需要了解如何在电脑上安装软件。如果你不知道如何做到这一点,请询问你办公室,学校里的人,或花钱找人来解释这个给你。 不建议给Maven的服务邮箱来发邮件寻求支持。 安装Mav...

fanl1982
2014/01/23
1.2W
7
TDD的测试框架--Machine.Specification

Machine.Specification 是一个 TDD 测试驱动开发的测试框架,简化了测试,无需关心语言本身特性。 Machine.Specifications 带来的好处是不需要在代码里有注释,但同时阅读代码的人可以一目了...

匿名
2013/01/22
1.1K
0
mvc框架--Razor

Razor 是一个轻巧而优雅的servlet mvc框架 # 又一个轮子? no,写就她是为了证实我个人的某些想法,并在这个过程中练练手,这两种冲动碰撞在一起,自然而然地产生了Razor # Razor的现在和未来...

dtubest
2013/01/25
3.1K
0

没有更多内容

加载失败,请刷新页面

加载更多

以渠道身份为数据背书,悟空榜如何呈现最真实的市场声音?

文 | 曾响铃 来源 | 科技向令说(xiangling0815) 时至今日,电商节已经成为各巨头零售平台例行的活动,花样在不断创新,玩法也在不断涌现。 在这个过程中,伴随电商节的各种品牌、产品销量榜...

曾响铃
前天
0
0
川普宣布拉黑微信支付!腾讯市值一度蒸发5000亿,45天后跟鹅厂发生交易都属违法

郭一璞 发自 凹非寺 量子位 报道 | 公众号 QbitAI 轮到腾讯和微信了。 谁都没想到,川普针对中国企业的举措会进展的这么快,就在刚刚,白宫官方网站po出一条总统行政命令: Executive Order ...

Java旅途
昨天
0
0
图解浏览器安全(同源策略、XSS、CSRF、跨域、HTTPS、安全沙箱等串成糖葫芦)

关注公众号“执鸢者”,获取大量教学视频并进入专业交流群,回复“安全”获取本节思维导图。 一天小林又去面试啦,面试官说:“小林呀,你对浏览器安全了解多少?”。小林摸了摸头说,目前我...

执鸢者
昨天
0
0
《乘风破浪的姐姐》:内容营销研究报告

《乘风破浪的姐姐》节目表现 大盘:同期热播的综艺中,《乘风破浪的姐姐》全面领先 6月12号以来,同期热播的综艺节目《乘风破浪的姐姐》播映指数排名第一,整体热度相对靠前;好评度、观看度等...

OSC_BMKOlH
昨天
0
0
TikTok遭遇十面埋伏的BGM,是美国Z时代人的抗议声 | 一周之最

原本是来中国街头吃吃吃,积累了不少粉丝的老外博主郭杰瑞,不知是不是因为央视的连线,顺应时势地变成了时政UP主,因疫情回到美国后,一直带着口罩在街头做采访,满足中国网友各种好奇。 从...

紫金山科技
前天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部