之前写了一篇用plugman工具生成cordova控件的文章,例子是参照网上比计较多的SimpleMath来尝试的,的确能够快速的生成SimpleMath控件,但是路径一直都不对,由于不需要做具体项目,也就是玩玩,没有太在意,现在公司主流产品需要细细研究下Cordova那么就有必要把自定义控件这一块内容给充实下了。而本文便是为了弄清楚Cordova自定义控件用到了些什么文件,各个文件配置和作用是什么。
根据官网给出的Echo插件定义流程,这篇文章便以自定义Echo插件为例子,来说明手动配置Cordova自定义插件的流程。
1、定义自定义插件
在说定义自定义控件之前先说说更改CordovaActivity默认包名的方法,cordova创建的文件目录io.cordova.helloworld包下会有一个CordovaActivity类型的MainActivty启动页,这里把它放在io.cordova.helloworld.activity目录下,自定义plugin放在io.cordova.helloworld.plugins目录下,当然这个可以根据自己的需求进行修改。
需要说明的是更改了CordovaActivity默认路径后,需要到cordova项目跟目录下找到config.xml文件中修改widget标签的id值为自己设定的CordovaActivity的package值,再添加android-packageName为自己的项目package值
然后在plugins目录下创建Echo.java插件,cordova的插件要求继承CordovaPlugin并实现execute方法,这个具体实现和参数传递网上很多资料可查,本文主要讲流程,这里就直接贴出Echo.java的代码
package io.cordova.hellocordova.plugins;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.json.JSONArray;
import org.json.JSONException;
public class Echo extends CordovaPlugin {
@Override
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
if (action.equals("echo")) {
String message = args.getString(0);
this.echo(message, callbackContext);
return true;
}
return false;
}
private void echo(String message, CallbackContext callbackContext) {
if (message != null && message.length() > 0) {
callbackContext.success(message);
} else {
callbackContext.error("Expected one non-empty string argument.");
}
}
}
Echo插件的代码就定义好了,从代码其实可以看出做的事情就是收到什么字符串就返回什么字符串,没有收到参数就作出错误提示。
2、将自定义插件和js代码发生关联
上一小节定义好了Echo插件,但是怎么通过js调用该插件是一个问题,本小节就来解决这个问题。首先,在cordova更目录/plugins目录下创建echo-plugin目录(这个目录名结合插件含义自己取),而echo-plugin目录下的文件结构如下图所示。
这里把echo-plugin的目录结构树也列出来吧,方便说明
其中的Echo.java文件,就是第一小节创建的Echo.java文件,直接拷贝过来就行了,而Echo.js文件则是调用Echo.js的方法(这个文件名自己随便取),这里贴出代码。
var exec = require('cordova/exec');
var myEchoFunc = function(){};
myEchoFunc.prototype.echo = function(success, error, arg0) {
exec(success, error, "Echo", "echo", arg0);
};
var MYECHOFUNC = new myEchoFunc();
module.exports = MYECHOFUNC;
看代码Echo.js引用了cordova/exec模块,实际就是引用了cordova.js,最终也是通过cordova.js文件通过一列的过程调用到Echo.java的execute方法,这边文章对这方面不作深入探究,有时间研究好了,再另写一篇文章。而myEchoFunc.prototype.echo扩展出来了echo方法,在使用时也表现为js端调用这个方法来调用Echo插件。
而真正起到桥梁作用的就是这里的plugin.xml了,贴出其代码。
<plugin id="echo-plugin" version="1.0.0" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
<name>Echoname>
<js-module name="echo" src="www/Echo.js">
<clobbers target="cordova.plugins.echo"/>
js-module>
<platform name="android">
<config-file parent="/*" target="res/xml/config.xml">
<feature name="Echo">
<param name="android-package" value="io.cordova.hellocordova.plugins.Echo"/>
feature>
config-file>
<config-file parent="/*" target="AndroidManifest.xml"/>
<source-file src="src/android/Echo.java" target-dir="io.cordova.hellocordova.plugins.Echo"/>
platform>
plugin>
其中plugin标签的id属性配置为echo-plugin目录名(这里叫echo-plugin所以就配置得“echo-plugin”),version为版本号,也可以自己改动。name标签根据具体插件含义取就行,后面会用到这个标签。而js-module标签的src属性定义了调用插件的js文件相对路径,name属性关系到其它js文件引用Echo.js文件的写法,根据含义自定义就好。clobbers标签制定了在js文件中发起插件调用的方法,比如在Echo.js中定义了调用插件的echo方法,那么在具体的使用时就可以通过cordova.plugins.echo.echo(success,fail,[params])来调用Echo插件。platfom标签定义平台,当然如有该标签用于多个平台这里也得有其他平台的platform标签。而第一个config-file标签表示在res/xml/config.xml目录中配置好插件,其中feature标签的name属性要和name标签定义的插件名称一致,param标签的value属性为插件包名.插件名构成,配置好这个config-file标签后在执行cordova run android时cordova应该自动会把feature标签内容拷贝到android项目中对应的res/xml/config.xml中,如果没有拷贝也一定要自己拷贝过去。第二个config-file标签指定了和插件对应的AndroidManifest.xml文件路径就在android项目的根目录下。source-file目录指定了echo-plugin目录下的Echo.java和android项目res/xml/config.xml中配置的feature标签的value值。个人觉得,应该是在echo-plugin目录下把以上目录文件都建好后,运行cordova build android或者cordoda run android命令cordova应该会根据这里的配置把Echo.java文件自定拷贝到android项目对应目录下,当然这个想法没有尝试过,感兴趣的童鞋可以测试下。
3、其他配置
由于cordova有其插件调用机制,只通过第一步第二部的配置是不行的,还有一些其它文件需要配置,其中包括配置cordova_plugins.js、android.json、fetch.json这几个文件,下面就来说说。
a、cordova_plugins.js文件配置
cordova_plugins.js文件在cordova根项目/www目录下,打开文件在module.exports模块中配置上自定义插件参数。
{
"id": "echo-plugin.echo",
"file": "plugins/echo-plugin/www/Echo.js",
"pluginId": "echo-plugin",
"clobbers": [
"cordova.plugins.echo"
]
}
其中,id由[pluginid].[js-module的name属性值]这两部分组成,file为Echo.js文件路径,clobbers为plugin.xml中clobbers标签对应的target属性值。配置好cordova_plugin.js后运行cordova run android会将该js文件拷贝到android项目的www目录下。
b、android.json文件配置
android.json在cordova根目录/plugins目录下,其代码为
{
"prepare_queue": {
"installed": [],
"uninstalled": []
},
"config_munge": {
"files": {}
},
"installed_plugins": {
"cordova-plugin-whitelist": {
"PACKAGE_NAME": "io.cordova.hellocordova"
},
"cordova-plugin-camera": {
"PACKAGE_NAME": "io.cordova.hellocordova"
},
"echo-plugin":{
"PACKAGE_NAME":"io.cordova.hellocordova.plugins"
}
},
"dependent_plugins": {
"cordova-plugin-compat": {
"PACKAGE_NAME": "io.cordova.hellocordova"
}
}
}
根据其它代码依样画瓢配置好自定义的插件就行,配置后这个后可以通过cordova plugin list列出自定义插件了。
c、fetch.json文件配置
fetch.json也是在cordova根目录/plugins目录下,作用为cordvoa运行时,检测到插件缺失会根据fetch.json的配置去加载对应的插件,代码为
{
"cordova-plugin-whitelist": {
"source": {
"type": "registry",
"id": "cordova-plugin-whitelist@1"
},
"is_top_level": true,
"variables": {}
},
"cordova-plugin-camera": {
"source": {
"type": "registry",
"id": "cordova-plugin-camera@^2.4.1"
},
"is_top_level": true,
"variables": {}
},
"cordova-plugin-compat": {
"source": {
"type": "registry",
"id": "cordova-plugin-compat@^1.1.0"
},
"is_top_level": false,
"variables": {}
},
"echo-plugin": {
"source": {
"type": "local",
"path": "E:\\KindomWorkSpace\\Study\\cordova\\my-cordova\\plugins\\echo-plugin"
},
"is_top_level": true,
"variables": {}
},
}
type设置为local指定自定义插件来自本地,is_top_level应该是表示直接可用的,而不是作为其它插件的依赖插件而存在。
到这里关于手动配置Cordova自定义插件的介绍几本算完了,当然有些配置我觉得应该是多余的,这篇文章说的配置方法肯定有简化的可能,希望尝试过的童鞋在留言里说说,大家共同学习。由于文章说的很清楚了(自我感觉),源码就不列出来,如果有需要的,可以留言,看到一定回复。
4、参考文献
关于参考,几本都是官网的一些文章,这里列出来吧
1、Android Plugin Development Guide:https://cordova.apache.org/docs/en/latest/guide/platforms/android/plugin.html
2、Plugin Development:Guidehttps://cordova.apache.org/docs/en/latest/guide/hybrid/plugins/index.html