最近公司把我从android组调到前端组来开发前端,公司用的框架是angularJS+ionic+cordova,我们知道用js写移动端,需求中免不了要调用android的相机、GPS、音频播放等功能,这时候我们就需要js和Java交互了,通过这个办法来调用android API。因此cordova给我提供了丰富的插件库,对于常用的插件我们可以去ngcordova官网看plugins,但是性能优化,很多的插件是满足不了我们实际开发的需要的,这时候我们怎么办呢,最好的办法就是自定义属于我们自己的插件。本篇博客为自定义插件抛砖引玉,来了解一下plugin到底是怎么写出来的。因为我主要做android,对于Java代码还是比较熟悉的,在开发过程中,通过使用
$ cordova plugin add xxx.xx.xx.cordova-plugin.imagePicker
cordova的插件时,在已添加的android platform中竟然插件完全变得跟android中library,这个让我很振奋,我想这样的话,我倒推回去,我写了很多的比较好的android library 按照道理同样可以写成插件来给自己用。所以经过我深入研究,发现这个是可以很容易实现的。恩恩,看到博客标题就知道我带着大家来实现一个关于dialog的plugin。
首先,我们来观察这个插件的构成。
[SweetAlertDialogPlugin github地址]
(https://github.com/Eddieyuan123/SweetAlertDialog)
src目录下有 android platform,android下有SweetAlertDialogPlugin.java文件,www下有SweetAlertDialogPlugin.js,根目录下有plugin.xml。因此得出结论插件必须要有这个文件。
plugin.xml
<?xml version='1.0' encoding='utf-8'?>
<plugin id="cn.pedant.sweetalert" version="1.0.0"
xmlns="http://apache.org/cordova/ns/plugins/1.0"
xmlns:android="http://schemas.android.com/apk/res/android">
<name>SweetAlertDialog</name>
<js-module name="SweetAlertDialog" src="www/SweetAlertDialog.js">
<clobbers target="window.plugins.SweetAlertDialogPlugin" />
</js-module><platform name="android">
<config-file parent="/*" target="res/xml/config.xml">
<feature name="SweetAlertDialogPlugin">
<param name="android-package" value="cn.pedant.sweetalert.SweetAlertDialogPlugin" />
</feature>
</config-file>
<config-file parent="/*" target="AndroidManifest.xml"></config-file>
<source-file src="src/android/SweetAlertDialogPlugin.java" target-dir="src/cn/pedant/sweetalert" />
<source-file src="src/android/OptAnimationLoader.java" target-dir="src/cn/pedant/sweetalert" />
<source-file src="src/android/Rotate3dAnimation.java" target-dir="src/cn/pedant/sweetalert" />
<source-file src="src/android/SuccessTickView.java" target-dir="src/cn/pedant/sweetalert" />
<source-file src="src/android/SweetAlertDialog.java" target-dir="src/cn/pedant/sweetalert" />
<source-file src="src/android/anim/dialog_scale_in.xml" target-dir="res/anim" />
<source-file src="src/android/anim/dialog_scale_out.xml" target-dir="res/anim" />
<source-file src="src/android/anim/error_frame_in.xml" target-dir="res/anim" />
<source-file src="src/android/anim/error_x_in.xml" target-dir="res/anim" />
<source-file src="src/android/anim/success_bow_roate.xml" target-dir="res/anim" />
<source-file src="src/android/anim/success_mask_layout.xml" target-dir="res/anim" />
<source-file src="src/android/drawable/blue_button_background.xml" target-dir="res/drawable" />
<source-file src="src/android/drawable/custom_img.jpg" target-dir="res/drawable" />
<source-file src="src/android/drawable/dialog_background.xml" target-dir="res/drawable" />
<source-file src="src/android/drawable/error_center_x.xml" target-dir="res/drawable" />
<source-file src="src/android/drawable/error_circle.xml" target-dir="res/drawable" />
<source-file src="src/android/drawable/gray_button_background.xml" target-dir="res/drawable" />
<source-file src="src/android/drawable/red_button_background.xml" target-dir="res/drawable" />
<source-file src="src/android/drawable/success_bow.xml" target-dir="res/drawable" />
<source-file src="src/android/drawable/success_circle.xml" target-dir="res/drawable" />
<source-file src="src/android/drawable/warning_circle.xml" target-dir="res/drawable" />
<source-file src="src/android/drawable/warning_sigh.xml" target-dir="res/drawable" />
<source-file src="src/android/values/alert_strings.xml" target-dir="res/values" />
<source-file src="src/android/values/alert_styles.xml" target-dir="res/values" />
<source-file src="src/android/values/attrs.xml" target-dir="res/values" />
<source-file src="src/android/values/alert_colors.xml" target-dir="res/values" />
<source-file src="src/android/layout/alert_dialog.xml" target-dir="res/layout" />
</platform>
</plugin>
这个文件的作用就是js和android的一些配置。下面慢慢来解释:
<js-module name="SweetAlertDialog" src="www/SweetAlertDialog.js">
<clobbers target="window.plugins.SweetAlertDialogPlugin" />
</js-module>
和Java交互的js文件,clobbers属性在angularJS中引用的名字。如何使用下面会详细说。
<config-file parent="/*" target="res/xml/config.xml">
<feature name="SweetAlertDialogPlugin">
<param name="android-package" value="cn.pedant.sweetalert.SweetAlertDialogPlugin" />
</feature>
</config-file>
param属性的value值代表的是包下的class文件,名字是SweetAlertDialogPlugin,这里要特别注意,因为我刚刚开始写插件的时候这里犯错了。
下面的一些代码就是把src中的这些文件添加到android platform中各个文件夹中,学过android的一看就懂。比如
<source-file src="src/android/layout/alert_dialog.xml" target-dir="res/layout" />
就是把alert_dialog.xml 这个布局文件复制到layout文件下。
SweetAlertDialogPlugin.java
package cn.pedant.sweetalert;
import com.ionicframework.tradeweb716543.TradeApp;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CallbackContext;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
/**
* This class echoes a string called from JavaScript.
*/
public class SweetAlertDialogPlugin extends CordovaPlugin {
@Override
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
if (action.equals("createNomalDialog")) {
String message = args.getString(0);
this.createNomalDialog(message, callbackContext);
return true;
}
return false;
}
private void createNomalDialog(String message, CallbackContext callbackContext) {
if (message != null && message.length() > 0) {
new SweetAlertDialog(TradeApp.getInstance().getActivity(),
SweetAlertDialog.NORMAL_TYPE)
.showCancelButton(true)
.setTitleText("sweet love")
.setContentText("sweet sweet love")
.show();
callbackContext.success(message);
} else {
callbackContext.error("Expected one non-empty string argument.");
}
}
}
SweetAlertDialogPlugin.js
var exec = require('cordova/exec');
var SweetAlertDialogPlugin = function(){
};
SweetAlertDialogPlugin.prototype.createNomalDialog = function(arg0, success, error) {
return exec(success, error, "SweetAlertDialogPlugin", "createNomalDialog", [arg0]);
};
var sweetAlertDialogPlugin = new SweetAlertDialogPlugin();
module.exports = sweetAlertDialogPlugin;
if(!window.plugins){
window.plugins = {};
}
if(!window.plugins.SweetAlertDialogPlugin){
window.plugins.SweetAlertDialogPlugin = sweetAlertDialogPlugin;
}
这两个文件要一起看,过程是这样的,我们用js这个createNomalDialog函数通过exec函数映射到sweetAlertDialogPlugin.java,找到sweetAlertDialogPlugin这类和createNomalDialog方法来执行,然后类通过callbackContext.success(message),callback回来。
整个插件的结构就是这样,分析清楚了,如何做才是重点,有两种方式,第一种肯定手写这3个文件。第二种可以通过plugman命令来管理插件。
1】执行安装命令,这个要在安装了nodeJS,cordova后才有用。
npm install -g plugman
2】新建一个插件SweetAlertDialogPlugin
plugman create –name –plugin_id –plugin_version [–path ] [–variable NAME=VALUE]
把其中的替换为 SweetAlertDialogPlugin;
替换为 cn.pedant.sweetalert
替换为 1.0.0
在终端中输入:
plugman create –name SweetAlertDialogPlugin –plugin_id cn.pedant.sweetalert –plugin_version 1.0.0
执行命令后会在当前目录下生成一个文件夹SweetAlertDialog。这里id和version对应上面plugin.xml中的id和version。
3】接着在终端中继续输入:
cd SweetAlertDialogPlugin
然后输入:
plugman platform add –platform_name android
这时候查看我们的SweetAlertDialog目录下的 src会新增一个目录android里面会有一个java文件:SweetAlertDialogPlugin .java
,当然这是一个生成的文件,因此我修改了成自己的Java代码。
上面我贴出来的代码就是我修改过的。
4】测试,添加插件
cordova plugin add SweetAlertDialog
这时在cordova自动帮你把src中的文件复制一份到android和iOS。继续看代码
window.plugins.SweetAlertDialogPlugin.createNomalDialog("messge",function(success){
alert(success);
},function(error){
alert(error);
})
上面提到
<clobbers target="window.plugins.SweetAlertDialogPlugin" />
在前端代码中就是这样用的。
好了,插件就这样可以用了。