Cordova Plugin

简介

A plugin is a package of injected code that allows the Cordova webview within which the app renders to communicate with the native platform on which it runs. Plugins provide access to device and platform functionality that is ordinarily unavailable to web-based apps. All the main Cordova API features are implemented as plugins, and many others are available that enable features such as bar code scanners, NFC communication, or to tailor calendar interfaces. There is a registry of available plugins.

安装和使用

安装

$ cordova plugin add xxx

注:xxx可以是plugin ID或者plugin的git镜像地址,比如系统状态栏的plugin ID是org.apache.cordova.statusbar 在git上面的镜像地址是https://git-wip-us.apache.org/repos/asf/cordova-plugin-device.git

获取plugin:

删除

$ cordova plugin remove xxx

自定义plugin

cordova项目目录结构:

├── platforms
|    ├── android
|    ├── ios
|    ├── wp7
|    └── ...
├── plugins
|    ├── org.apache.cordova.statusbar
|    └── ...
├── config.xml
└── www

platforms是项目支持的平台,可以通过$ cordova platform add ios添加新的平台,plugins是安装的插件目录,我们从cordova下载的插件和我们自己扩展的插件最终都是要添加在plugins目录中,config.xml是项目的配置信息文件,www是web工程目录。

扩展cordova plugin需要按照固定的目录结构创建,最终plugin源码对应的目录为:

StatusBar
├── src
|    ├── android
|    |    └── StatusBar.java
|    ├── ios
|    |    └── CDVStatusBar.h
|    |    └── CDVStatusBar.m
|    └── ...
├── www
|    └── StatusBar.js
└── plugin.xml

src对应的是不同平台实现plugin的源码,www存放javascript,plugin.xml是plugin的配置文件。 plugin.xml的配置信息如下:

`\

<name>StatusBar</name>
<description>扩展的cordova插件</description>
<license>Apache 2.0</license>
<keywords>cordova,statusbar</keywords>

<js-module src="www/StatusBar.js" name="StatusBar">
    <clobbers target="cordova.plugins.StatusBar"/>
</js-module>

<!-- android -->
<platform name="android">
    <config-file target="res/xml/config.xml" parent="/*">
        <feature name="StatusBar">
            <param name="android-package" value="com.sf.cordova.StatusBar"/>
        </feature>
    </config-file>

    <source-file src="src/android/StatusBar.java" target-dir="src/com/sf/cordova/statusbar" />
</platform>

<!-- ios -->
<platform name="ios">
    <config-file target="config.xml" parent="/*">
        <feature name="StatusBar">
            <param name="ios-package" value="CDVStatusBar"/>
        </feature>
    </config-file>
    <header-file src="src/ios/CDVStatusBar.h" />
    <source-file src="src/ios/CDVStatusBar.m" />

`\

  • id:cordova plugin ID
  • name:plugin 名称
  • js-module:javascript文件配置信息
  • platform:插件支持的平台

StatusBar.js的内容为:

`\ var exec = require(‘cordova/exec’);

exports.hideStatusBar = function(success, error) { exec(success, error, “StatusBar”, “hideStatusBar”, []); }; `\ 第一个hideStatusBar为暴露给JS的接口,第二个hideStatusBar是暴露给平台的接口,各平台需要实现各自的逻辑。 其中IOS平台需要继承CDVPlugin,并实现StatusBar.js中配置的接口,CDVStatusBar.m内容如下

`\

import “CDVStatusBar.h”

import <objc/runtime.h>

import <Cordova/CDVViewController.h>

@implementation CDVStatusBar

  • (void)hideStatusBar:(CDVInvokedUrlCommand)command { CDVPluginResult pluginResult = nil; NSString* echo = @”隐藏StatusBar”;//这个地方是处理的结果,也就是native 的要返回给前端界面的参数,
    NSLog(@”echo==%@”,echo); if (echo != nil && [echo length] > 0) { pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:echo]; } else { pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR]; }

    [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; }

@end `\ Android平台的StatusBar.java需要继承CordovaPlugin类,重写execute(),使用 action 来判断我们在 javascript 中调用的方法名,成功的话调用 callbackContext.success(message),失败调用 callbackContext.error(message) 方法,分别对应 javascript 文件中的 success 和 error 回调函数。 StatusBar.java的内容为:

`\ package com.sf.cordova.statusbar;

public class StatusBar extends CordovaPlugin {

public boolean execute(String action, JSONArray args, CallbackContext callbackContext) 
        throws JSONException {
    Activity activity = this.cordova.getActivity();
    if (action.equals("hideStatusBar")) {
        Intent i = activity.getIntent();
        if (i.hasExtra(Intent.EXTRA_TEXT)) {
            callbackContext.success(i.getStringExtra(Intent.EXTRA_TEXT));
        } else {
            callbackContext.error("");
        }
        return true;
    }
    return false;
}

} `\

完成插件的编写,通过cordova的命令添加plugin:

cordova plugin add StatusBar

项目plugins目录下会生成自定义的插件。

使用Plugin

在前端页面的JS中调用插件代码:

var statusbar = cordova.require('com.sf.cordova.statusbar.StatusBar');

statusbar.hideStatusBar(function(message) {
    // alert(message);
}, function(message) {
    // alert(message);
});

发布Plugin

开发好的plugin,如果想分享到Cordova registry,可以使用cordova提供的插件管理工具plugman发布上去,步骤如下:

$ plugman adduser # that is if you don't have an account yet
$ plugman publish /path/to/your/plugin

Hybrid选型及设计原理(转)

手机App方案

WEB APP

DEFINITION 定义

A web application or web app is any software that runs in a web browser. It is created in a browser-supported programming language (such as the combination of JavaScript, HTML and CSS) and relies on a web browser to render the application.
Web applications are popular due to the ubiquity of web browsers, and the convenience of using a web browser as a client, sometimes called a thin client. The ability to update and maintain web applications without distributing and installing software on potentially thousands of client computers is a key reason for their popularity, as is the inherent support for cross-platform compatibility. Common web applications include webmail, online retail sales, online auctions, wikis and many other functions. –wiki

在浏览器端构建的基于HTML/CSS/JS进行开发,使用浏览器进行渲染的应用程序。

其特点体现在几个方面

  1. update and maintain web applications without distributing and installing software 升级和维护不需要分发和安装
  2. the inherent support for cross-platform compatibility 良好的跨平台性

STORY 小故事

The full Safari engine is inside of iPhone. And so, you can write amazing Web 2.0 and Ajax apps that look exactly and behave exactly like apps on the iPhone. And these apps can integrate perfectly with iPhone services. They can make a call, they can send an email, they can look up a location on Google Maps. And guess what? There’s no SDK that you need! You’ve got everything you need if you know how to write apps using the most modern web standards to write amazing apps for the iPhone today. So developers, we think we’ve got a very sweet story for you. You can begin building your iPhone apps today. –Steve Jobs

Jobs其实是最早的web app的倡导者之一,在当时的构想中是没有native app这种形式的,所有的app都是以web的形式存在的,但是当时的Jobs需要面对两个问题

  1. 移动网络根本无力承担这种变革
  2. 如何让webapp盈利
  3. webapp运行的体验非常糟糕

而基于此的讨论和考虑才逐步衍生出后来的Native App和App Store

阅读

CASE STUDY 案例

Native App

DIFINITION 定义

Apps are usually available through application distribution platforms, which began appearing in 2008 and are typically operated by the owner of the mobile operating system, such as the Apple App Store, Google Play, Windows Phone Store, and BlackBerry App World. Some apps are free, while others must be bought. Usually, they are downloaded from the platform to a target device, such as an iPhone, BlackBerry, Android phone or Windows Phone, but sometimes they can be downloaded to laptops or desktop computers. For apps with a price, generally a percentage, 20-30%, goes to the distribution provider (such as iTunes), and the rest goes to the producer of the app.1 The same app can therefore cost the average Smartphone user a different price depending on whether they use iPhone, Android, or BlackBerry 10 devices. –wiki

基于手机操作系统的应用程序,使用其原生程序进行构建

其特点体现在几个方面

  1. operated by the owner of the mobile operating system 在对应操作系统平台进行应用程序的开发
  2. available through application distribution platforms 需要分发应用(下载)的市场

CASE STUDY 案例

HYBRID APP

DEFINITION 定义

A hybrid mobile application (or hybrid mobile app) is a mobile application that runs inside of a native container and leverages the device’s web browser to display locally hosted HTML pages.[29] Hybrid mobile apps are composed mostly of HTML, JavaScript, and CSS. Device specific functionalities such as camera access, geolocation, and accelerometer readings are exposed through a JavaScript API. –wiki

其特点体现在几个方面

  1. runs inside of a native container 运行在原生的容器内
  2. Device specific functionalities are exposed through a JavaScript API 通过JS API暴露底层的功能接口

优缺点

Pros

  • Hybrid mobile apps allow code reuse across platforms. Let the library or framework you are using take care of the platform specific differences and use the same JavaScript code on both platforms.
  • JavaScript is something that many developers are already familiar with where something like the iOS development tools are more specialized. It can be argued that there is less of a learning curve when developing hybrid mobile apps compared to native apps.
  • The app’s interface and logic can be built and debugged in the web browser using an emulation framework. This could lower development costs depending on the tools required to develop native apps for the target platforms.
  • The HTML5 application development with CSS3 gives the compelling structure to the interface of game app and this ensures pleasing user-interface.

Cons

  • Hybrid mobile apps are more susceptible to user interface lag due to the extra layers of abstraction.[29]
    Only a certain subset of native functionality is available which depends on the framework. All others native functions are accessible developing Plugins
  • As for native apps, the hybrid code base requires recompilation and resubmission to the distribution network where it is possible to instantly update a mobile web app’s codebase.

  • HTML5 in mobile devices

CASE STUDY 案例

选择

WEB APP, HYBRID APP & NATIVE APP 选择哪种形态?

codeWEB APP/code, codeHYBRID APP/code & codeNATIVE APP/code 选择哪种形态?

决定哪种模式之前需要问自己这些问题:

  1. App的体验和开发周期何者为先?
  2. APP的更新周期是否频繁?
  3. 开发资源
  4. 应用平台

Hybrid App模型

在native与web之间构建一层bridge, 将底层的接口映射到JS API上

  1. View的渲染依赖于浏览器自身的渲染引擎,即使游戏也不需要去写openGL
  2. Bridge在不同的平台通过不同的native层实现,在各自平台下完成编译
  3. Business可以实现在Web也可以实现在Native
  4. Plugin构成了Bridge的扩展

现有平台

案例

使用js编写通用的业务逻辑,使用nodejs编译不同平台的native app

  1. View通过Ti.UI进行调用Native实现,在不同的操作系统中调用不同的Native UI实现。Ti.UI可以定义部分Native UI
  2. Business通过JS编写最后编译成Native代码
  3. Bridge和Build工具进行了整合,理论上可以跨所有平台(meta programming?)

现有平台

案例

Hybrid App实现原理

Titanium严格来说不属于Hybrid,因为其最终产生的仍然是Native App,过于牛B,不在本文知识范围内。本文限于讨论类似Cordova的Hybrid实现。

Native调用JS

图片描述

  1. native通过string调用js
  2. webview调用js解释器的eval方法将string转化为js方法
  3. webview调用js方法

JS调用Native

图片描述

  1. javascript改变url,通过url传递调用的方法和参数
  2. webview监听到了URL变化,并且探测到url中定义的方法和参数
  3. 寻找对应的映射表,找到native对应接口api进行调用
  4. 执行javascript调用方法时传入的回调string并添加数据
  5. webview解析string转化为javascript进行调用

URL Schemes

为了区别普通的http访问的url与hybrid调用native的url,参考openurl的标准apple提出了url schema的方法

系统自定义了可以被识别的协议和url,例如

  • mailto:frank@wwdcdemo.example.com
  • tel:1-408-555-5555
  • sms:1-408-555-1212

app自身可以自定义url schema,并且把自定义的url注册在调度中心, 例如

  • ctrip://wireless 打开携程App
  • weixin:// 打开微信

阅读

早期的Android采用了JavascriptInterface,但是这种方案存在注入的安全隐患,所以在Android 4.0以上的版本开始就支持了URL Schema方案

Hybrid URL Schema在实现中的问题

  1. 存在短时间内高并发的问题,例如:一次定位没有完成期间,反复调用定位
  2. 执行http的url访问还没有返回就调用了url schema,导致了前一次行为没有生效
  3. 在ios中native调用js是实时的,在Android中native调用js是异步的,在异步调用中出现alert这种阻塞进程的会直接crash app

针对Hybrid使用中出现的这些问题,cordova做了精致的封装。

文章转自leewind