[Cordova] Plugin开发入门
[Cordova] Plugin开发入门
Overview
Cordova的设计概念,是在APP上透过Web控件来呈现Web页面,让Web开发人员可以操作熟悉的语言、工具来开发APP。使用Web页面来呈现功能内容,的确可以满足大部分的功能需求,但是因为APP的使用情景毕竟有别于Web,某些APP的功能需求像是:拨打电话、扫描条形码...等等,无法单纯使用Web开发技术就能实现。
为了让Web页面能够满足更多的APP功能需求,Cordova提供了Plugin机制,让Web页面能够挂载并调用Native开发技术所开发的功能模块。当开发人员遇到Web开发技术无法实现的功能需求时,可以到Cordova官网(https://cordova.apache.org/plugins/),下载并使用官方提供的各种通用Plugin功能模块。而就算遇到了特殊的功能需求,Cordova也提供了方法,让开发人员可以自行开发专属于自己的客制Plugin功能模块。
本篇文章介绍如何建立一个Cordova Plugin功能模块,让开发人员能够使用Native开发技术,在Cordova里开发Plugin功能模块给Web页面使用,让Web页面能够满足更多的APP功能需求。主要是为自己留个纪录,也希望能帮助到有需要的开发人员。
Cordova Plugin Metadata
Cordova Plugin功能模块会以文件夹的形式,存放于本机文件系统或是远程Git服务器。使用Visual Studio开发Cordova项目的时候,只要输入档案路径或是服务器路径,就可以自动完成挂载Plugin功能模块的动作。
挂载Plugin功能模块的时候,Visual Studio会读取文件夹下的「plugin.xml」。这个XML档案中定义了Plugin功能模块的相关设定项目,这些设定项目里用于描述Plugin功能模块的,主要项目为:
- id : Plugin标识符
- version : Plugin版本
- name : Plugin名称
- description : Plugin描述
- license : Plugin授权模式
- js-module : 各个JavaScript模块的设定项目
- platform : 各个执行平台的设定项目
<?xml version="1.0" encoding="UTF-8"?>
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
id="clk-cordova-sample"
version="1.0.0">
<!-- metadata -->
<name>CLK Cordova Sample</name>
<description>CLK Cordova Sample的说明</description>
<license>Apache 2.0</license>
<!-- javascript -->
<js-module>...</js-module>
<js-module>...</js-module>
<!-- android -->
<platform name="android">...</platform>
<!-- ios -->
<platform name="ios">...</platform>
</plugin>
Android Platform Plugin
platform metadata
Cordova在编译Android Platform Plugin的时候,会先建立编译用的Android项目,并且读取plugin.xml里被标注为android的platform设定区块,做为编译时期的编译参数。
<!-- android -->
<platform name="android">
<!-- config -->
<config-file target="res/xml/config.xml" parent="/*">
<feature name="NotificationService">
<param name="android-package" value="com.clk.cordova.sample.NotificationService"/>
</feature>
</config-file>
<!-- source -->
<source-file src="src/android/NotificationService.java" target-dir="src/com/clk/cordova/sample/" />
</platform>
source-file
当Cordova读取到Android platform的设定区块的source-file设定区块时,会将每一个source-file设定区块里src所指定的档案,复制到Android项目里target-dir所指定文件夹,用以进行后续的编译工作。在本篇的范例里,source-file设定区块所代表的意义是:将Plugin里src/android/NotificationService.java的这个档案,复制到Android项目的src/com/clk/cordova/sample/文件夹里面来进行编译。
<!-- source -->
<source-file src="src/android/NotificationService.java" target-dir="src/com/clk/cordova/sample/" />
config-file
Android platform的设定区块的config-file设定区块比较特别,这个设定区块是用来,定义提供给Web页面调用的类别。在这其中feature name代表的是这个Plugin提供给Web页面使用的类别别名,而param value里定义的则是实际提供服务的Native类别名称,剩余其他设定参数则是编译所需的固定参数。在本篇范例里,config-file设定区块所代表的意义是:Web页面可以使用NotificationService这个类别别名,来调用Android项目里面的com.clk.cordova.sample.NotificationService这个Native类别。
<!-- config -->
<config-file target="res/xml/config.xml" parent="/*">
<feature name="NotificationService">
<param name="android-package" value="com.clk.cordova.sample.NotificationService"/>
</feature>
</config-file>
native code
Android platform plugin里,使用Native技术所开发的Native类别,必须先继承org.apache.cordova.CordovaPlugin这个类别,再经由source-file设定加入项目编译,后续才可以透过config-file的定义提供Web页面调用。而Web页面调用Native类别时,Cordova会执行Native类别的execute方法,并且提供下列内容:
- action : 方法名称。
- 因为只有execute一个进入点,所以使用action来分发方法,让一个Class能够提供更多方法。
- args : 方法参数。
- 对应方法名称的参数内容、为JSONArray格式。
- callbackContext : 方法回呼。
- 方法成功时呼叫callbackContext.success回传成功结果、方法失败时呼叫callbackContext.error回传错误讯息。
- return : 是否接受调用。
- 方法成功时回传true、方法失败时回传false。
package com.clk.cordova.sample;
import org.apache.cordova.*;
import org.json.*;
import android.widget.Toast;
public class NotificationService extends CordovaPlugin {
// methods
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
// show
if(action.equals("show")) {
// arguments
String message = args.getString(0);
// execute
Toast.makeText(this.cordova.getActivity(), message, Toast.LENGTH_LONG).show();
// return
return true;
}
// default
return false;
}
}
cordova.exec
完成上述Android Platform Plugin的相关开发工作之后,在挂载这个Cordova Plugin的Android执行平台里,Web页面就可以使用统一的cordova.exec方法,来调用Native开发的类别。这个cordova.exec接口会执行Native类别的execute方法,并且带入下列内容:
- success : 方法成功时的Callback函式。
- error:方法失败时的Callback函式。
- feature:config-file设定区块所定义的类别别名。
- action:Native类别提供的方法名称。
- args:Native类别提供的方法参数。
cordova.exec(success, error, feature, action, args);
iOS Platform Plugin
platform metadata
Cordova在编译iOS Platform Plugin的时候,会先建立编译用的iOS项目,并且读取plugin.xml里被标注为ios的platform设定区块,做为编译时期的编译参数。
<!-- ios -->
<platform name="ios">
<!-- config -->
<config-file target="config.xml" parent="/*">
<feature name="NotificationService">
<param name="ios-package" value="CLKNotificationService"/>
</feature>
</config-file>
<!-- source -->
<header-file src="src/ios/CLKNotificationService.h" />
<source-file src="src/ios/CLKNotificationService.m" />
</platform>
source-file
当Cordova读取到iOS platform的设定区块的source-file设定区块时,会将每一个source-file设定区块里src所指定的档案,复制到iOS项目的Plugin文件夹,用以进行后续的编译工作。在本篇的范例里,source-file设定区块所代表的意义是:将Plugin里src/ios/CLKNotificationService.h跟CLKNotificationService.m的这两个档案,复制到iOS项目的Plugin文件夹里面来进行编译。
<!-- source -->
<header-file src="src/ios/CLKNotificationService.h" />
<source-file src="src/ios/CLKNotificationService.m" />
config-file
iOS platform的设定区块的config-file设定区块比较特别,这个设定区块是用来,定义提供给Web页面调用的类别。在这其中feature name代表的是这个Plugin提供给Web页面使用的类别别名,而param value里定义的则是实际提供服务的Native类别名称,剩余其他设定参数则是编译所需的固定参数。在本篇范例里,config-file设定区块所代表的意义是:Web页面可以使用NotificationService这个类别别名,来调用iOS项目里面的CLKNotificationService这个Native类别。
<!-- config -->
<config-file target="config.xml" parent="/*">
<feature name="NotificationService">
<param name="ios-package" value="CLKNotificationService"/>
</feature>
</config-file>
native code
iOS platform plugin里,使用Native技术所开发的Native类别,必须先继承CDVPlugin这个类别,再经由source-file设定加入项目编译,后续才可以透过config-file的定义提供Web页面调用。而Web页面调用Native类别时,Cordova会依照Web页面所提供的action参数,来执行Native类别里同名的方法,并且提供下列内容:
CDVInvokedUrlCommand : 执行指令
- @property (nonatomic, readonly) NSString* callbackId; : 回呼编号
- (id)argumentAtIndex:(NSUInteger)index; : 取得输入参数
CDVPluginResult : 执行结果
- @property (nonatomic, strong, readonly) NSNumber* status; : 执行结果(Ex:成功、失败...)
- @property (nonatomic, strong, readonly) id message; : 回传参数(Ex:String、Bool...)
CDVPlugin(self) : 继承的CDVPlugin
- @property (nonatomic, weak) id commandDelegate; : 回传执行结果物及回呼编号
// CLKNotificationService.h
#import <Foundation/Foundation.h>
#import <Cordova/CDVPlugin.h>
@interface CLKNotificationService : CDVPlugin
// methods
-(void)show:(CDVInvokedUrlCommand*)command;
@end
// CLKNotificationService.m
#import "CLKNotificationService.h"
@implementation CLKNotificationService
// methods
- (void)show:(CDVInvokedUrlCommand*)command
{
// arguments
NSString* message = [command argumentAtIndex:0];
// execute
[[[UIAlertView alloc] initWithTitle:nil message:message delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
}
@end
cordova.exec
完成上述iOS Platform Plugin的相关开发工作之后,在挂载这个Cordova Plugin的iOS执行平台里,Web页面就可以使用统一的cordova.exec方法,来调用Native开发的类别。这个cordova.exec接口会提供action参数,来执行Native类别里同名的方法,并且带入下列内容:
- success : 方法成功时的Callback函式。
- error:方法失败时的Callback函式。
- feature:config-file设定区块所定义的类别别名。
- action:Native类别提供的方法名称。
- args:Native类别提供的方法参数。
cordova.exec(success, error, feature, action, args);
JavaScript Module Plugin
Cordova提供统一的cordova.exec方法,让Web页面调用Native开发的Plugin功能。但是,cordova.exec方法需要带入的五个输入参数、加上success、error这两个Callback函式所隐含的回传参数、再加上多参数需要包装成JSON格式...这些琐碎的工作,会大量增加Web开发人员使用Plugin功能模块的负担。
为了减少Web开发人员使用Plugin功能模块的负担,Plugin功能模块的开发人员,可以使用Cordova提供的JavaScript Module挂载机制,在Plugin功能模块里面加入JavaScript程序代码来封装cordova.exec方法,用以提供更简洁、更易懂的使用接口让Web开发人员使用。
Before
cordova.exec(null, null, "NotificationService", "show", [message]);
After
clk.cordova.sample.NotificationService.show("Clark");
js-module metadata
Cordova在编译每个执行平台的时候,会读取plugin.xml里所有的js-module设定区块,并且将每一个js-module设定区块里src所指定的js-module原始码打包备用。当应用程序执行的时候,Cordova核心会将这些js-module加载来提供Web页面使用。
- name : js-module标识符
- src : js-module原始码
<!-- javascript -->
<js-module name="NotificationService" src="www/clk.cordova.sample.NotificationService.js" >
...
</js-module>
js-module code
在每个js-module原始码的内部,可以透过Cordova所提供的exports对象,来附加使用JavaScript所撰写的功能函式,这个exports对象是用来封装js-module功能的对象。在本篇的范例里,js-module原始码在exports对象上,附加了一个show函式用来简化cordova.exec的使用方式,提供给Web页面使用。
clk.cordova.sample.NotificationService.js
// methods
exports.show = function (message) {
cordova.exec(null, null, "NotificationService", "show", [message]);
};
cordova.require
Web页面需要使用js-module的时候,可以使用cordova.require方法来取得js-module。这个cordova.require方法,使用js-module设定区块里name所设定的名称、加上Plugin metadata里所定的id标识符做为索引,来识别并取得Cordova核心中的js-module。在本篇的范例里,Web页面使用cordova.require取得Plugin id:clk-cordova-sample、js-module name:NotificationService,封装js-module的exports对象,并且调用这个exports对象所附加的show函式。
index.html
var notificationService = cordova.require("clk-cordova-sample.NotificationService"); notificationService.show("Clark");
clobbers
为了更进一步简化取得js-module的方式,Cordova另外在plugin.xml的js-module设定区块上,提供了clobbers设定项目。当应用程序执行、Cordova核心加载js-module提供Web页面使用的时候,如果定义了clobbers所提供的target设定参数,Cordova核心会自动将封装js-module的exports对象,存放到target所定义的对象上,让Web页面可以直接调用。
在本篇的范例里,js-module定义了一个clobbers的target,Cordova核心会在载入clk.cordova.sample.NotificationService.js之后,将封装js-module的exports对象,存放到clk.cordova.sample.NotificationService这个物件上。后续Web页面,只要直接使用clk.cordova.sample.NotificationService.show就可以调用这个exports对象所附加的show函式。
clobbers
<!-- javascript -->
<js-module name="NotificationService" src="www/clk.cordova.sample.NotificationService.js" >
<clobbers target="clk.cordova.sample.NotificationService" />
</js-module>
index.html
clk.cordova.sample.NotificationService.show("Clark");
范例下载
范例程序代码:下载地址
[Cordova] Plugin开发入门的更多相关文章
- [Cordova] Plugin开发架构
[Cordova] Plugin开发架构 问题情景 开发Cordova Plugin的时候,侦错Native Code是一件让人困扰的事情,因为Cordova所提供的错误讯息并没有那么的完整.常常需要 ...
- Visual Studio 2015 和 Apache Cordova 跨平台开发入门
原文:Visual Studio 2015 和 Apache Cordova 跨平台开发入门(一) 基于 Windows 10 的 Visual Studio 2015 跨平台的应用开发主要分为基于V ...
- Visual Studio 2015 和 Apache Cordova 跨平台开发入门(一)
基于 Windows 10 的 Visual Studio 2015 跨平台的应用开发主要分为基于Visual Studio 安装 Xamarin 扩展的跨Android.iOS 和 Windows的 ...
- [Cordova] Plugin里使用iOS Framework
[Cordova] Plugin里使用iOS Framework 前言 开发Cordova Plugin的时候,在Native Code里使用第三方Library,除了可以加速项目的时程.也避免了重复 ...
- [Cordova] Plugin里使用Android Library
[Cordova] Plugin里使用Android Library 前言 开发Cordova Plugin的时候,在Native Code里使用第三方Library,除了可以加速项目的时程.也避免了 ...
- Cordova 3.x入门 - 目录
这个系列是基于Cordova 3.x的,很多Android的东西都是Eclipse ADT+Ant的,而目前Android的开发已经完全切换到了Android Studio+Gradle,需要大家特别 ...
- JavaWeb学习总结(一)——JavaWeb开发入门
http://www.cnblogs.com/xdp-gacl/p/3729033.html 只为成功找方法,不为失败找借口! JavaWeb学习总结(一)--JavaWeb开发入门 一.基本概念 1 ...
- HTML5手机APP开发入门(1)
HTML5手机APP开发入门(1) 开发框架 Ionicframework V2 + Angular 2 具体内容可以参考一下网站 http://ionicframework.net/ http:// ...
- phonegap开发入门
做了几次开发配置了,但时间一长就忘了,特记录一下. 一.环境变量配置::右击“我的电脑”-->"高级"-->"环境变量" 1.在系统变量里新建JAV ...
随机推荐
- 通过bootstrap来学习less
很早之前就听说过less了,但是一直拖着没去学习.最近抽空看了less,其实语法很简单,看一遍基本就知道怎么用了.平时自己写页面用less的话,感觉是方便了些,但是难道less的好处就只是这样? 刚好 ...
- [转] 移动前端不得不了解的HTML5 head 头标签
HTML的头部内容特别多,有针对SEO的头部信息,也有针对移动设备的头部信息.而且各个浏览器内核以及各个国内浏览器厂商都有些自己的标签元 素,有很多差异性.移动端的工作已经越来越成为前端工作的重要内容 ...
- Web应用安全之文件上传漏洞详解
什么是文件上传漏洞 文件上传漏洞是在用户上传了一个可执行的脚本文件,本通过此脚本文件获得了执行服务器端命令的功能,这种攻击方式是最为直接,最为有效的,有时候,几乎没有什么门槛,也就是任何人都可以进行这 ...
- <C#>找出数组中重复次数最多的数值
给定一个int数组,里面存在重复的数值,如何找到重复次数最多的数值呢? 这是在某社区上有人提出的问题,我想到的解决方法是分组. 1.先对数组中的所有元素进行分组,那么,重复的数值肯定会被放到一组中: ...
- 使用Google产品以来遇到的最糟糕、最霸道、最让人抓狂的设计
很久没有登录cnblogs@gmail.com这个邮箱,今天通过gmail.com登录了一下,登录后出现一个对话框要求设置性别与出生日期,而且必须要设置,不设置不让登录. 这个邮箱是我们网站用的是邮箱 ...
- java之初识服务器跨域获取数据
当一个项目膨大到无法进行整理时,而作为新负责维护的团队是非常苦恼的.对于想实现两个系统的数据访问,使用Ajax数据请求方式获取jsonp格式的数据 需要有前端jquery库文件. 前端代码通过jque ...
- 【web前端面试题整理02】前端面试题第二弹袭来,接招!
前言 今天本来准备先了解下node.js的,但是,看看我们一个小时前与一个小时后的差距: 既然如此,我们继续来搜集我们的前端面试题大业吧!!! 特别感谢玉面小肥鱼提供哟,@玉面小飞鱼 题目一览 Jav ...
- Fort.js – 时尚、现代的表单填写进度提示效果
Fort.js 是一款用于时尚.现代的表单填写进度提示效果的 JavaScript 库,你需要做的就是添加表单,剩下的任务就交给 Fort.js 算法了,使用非常简单.提供了Default.Gradi ...
- Bise IE6 在你的网站上加上它让IE滚蛋吧
<!--[if lt IE 7]> <style type="text/css"> .broswer_tips{height:26px;background ...
- elasticsearch中的API
elasticsearch中的API es中的API按照大类分为下面几种: 文档API: 提供对文档的增删改查操作 搜索API: 提供对文档进行某个字段的查询 索引API: 提供对索引进行操作 查看A ...