关于在cordova的插件开发的做定义消息的功能没有官方的介绍文章,但是官方有一个这样的例子,就是电源状态插件。我们通过学习这个插件的编写来学习自定义消息。
这个插件的地址为:https://github.com/apache/cordova-plugin-battery-status
安装方法为:cordova plugin add cordova-plugin-battery-status
使用方法是:在自己的js工程里执行以下几句话:
window.addEventListener("batterystatus", onBatteryStatus, false); function onBatteryStatus(status) { console.log("Level: " + status.level + " isPlugged: " + status.isPlugged);}分别是给工程添加插件自定义的消息事件,并指定消息响应函数
在我的测试例子中,使用了如下函数为两个按键的响应函数,一个订阅消息,一个取消订阅:
function onBatteryStatus(info) { alert("BATTERY STATUS: Level: " + info.level + "isPlugged: " + info.isPlugged);}$scope.onbatteryStartBtn = function() { alert("onStartBtn"); window.addEventListener("batterystatus",onBatteryStatus, false);};$scope.onbatteryStopBtn = function() { alert("onStopBtn"); window.removeEventListener("batterystatus",onBatteryStatus);};
然后编译工程:ionic build android
在手机上测试:ionic run android
这里显然就是典型的回调机制,就是在自己的工程里定制消息的响应回调函数,然后当产生这个消息的话,回调函数就会被调用。
那么接下来看一下这个电池状态插件是怎样实现的。
var cordova = require('cordova'), exec = require('cordova/exec');var STATUS_CRITICAL = 5;var STATUS_LOW = 20;var Battery = function() { this._level = null; this._isPlugged = null; // Create new event handlers on thewindow (returns a channel instance) this.channels = { batterystatus:cordova.addWindowEventHandler("batterystatus"), batterylow:cordova.addWindowEventHandler("batterylow"), batterycritical:cordova.addWindowEventHandler("batterycritical") }; for (var key in this.channels) { this.channels[key].onHasSubscribersChange= Battery.onHasSubscribersChange; }};function handlers() { return battery.channels.batterystatus.numHandlers+ battery.channels.batterylow.numHandlers+ battery.channels.batterycritical.numHandlers;}/** * Event handlers for when callbacks getregistered for the battery. * Keep track of how many handlers wehave so we can start and stop the native battery listener * apPRopriately (and hopefully save onbattery life!). */Battery.onHasSubscribersChange = function() { // If we just registered the firsthandler, make sure native listener is started. if (this.numHandlers === 1 && handlers()=== 1) { exec(battery._status, battery._error,"Battery", "start", []); } else if (handlers() === 0) { exec(null, null, "Battery","stop", []); }};/** * Callback for battery status * * @param {Object} info keys: level, isPlugged */Battery.prototype._status = function (info) { if (info) { if (battery._level !== info.level|| battery._isPlugged !== info.isPlugged) { if(info.level === null &&battery._level !== null) { return; // special casewhere callback is called because we stopped listening to the native side. } // Something changed. Firebatterystatus event cordova.fireWindowEvent("batterystatus",info); if (!info.isPlugged) { // donot fire low/critical if we are charging. issue: CB-4520 // note the following areNOT exact checks, as we want to catch a transition from // above the threshold tobelow. issue: CB-4519 if (battery._level >STATUS_CRITICAL && info.level <= STATUS_CRITICAL) { // Fire criticalbattery event cordova.fireWindowEvent("batterycritical",info); } else if (battery._level >STATUS_LOW && info.level <= STATUS_LOW) { // Fire low battery event cordova.fireWindowEvent("batterylow",info); } } battery._level = info.level; battery._isPlugged = info.isPlugged; } }};/** * Error callback for battery start */Battery.prototype._error = function(e) { console.log("Error initializingBattery: " + e);};var battery = new Battery(); // jshint ignore:linemodule.exports = battery;
其中,exec(battery._status, battery._error, "Battery","start", []);
用来让插件的js代码和硬件本地代码联系起来。
整个插件的工作原理是:
1. 定义自定义消息
2. 调用端增加对自定义消息的接听(addEventListener)
3. 本地产生消息,通过exec函数指定的回调函数来响应。,然后在相应函数里,激发自定义消息。(fireWindowEvent)
4. 接听者收到消息和参数
其中自定义消息部分是:
// Create newevent handlers on the window (returns a channel instance) this.channels = { batterystatus:cordova.addWindowEventHandler("batterystatus"), batterylow:cordova.addWindowEventHandler("batterylow"), batterycritical:cordova.addWindowEventHandler("batterycritical") }; for (var key in this.channels) { this.channels[key].onHasSubscribersChange= Battery.onHasSubscribersChange; }};
这里共定义了三条消息。格式参考以上格式,
当有人注册这个自定义消息的时候会响应以下函数:
/** * Event handlers for when callbacks getregistered for the battery. * Keep track of how many handlers wehave so we can start and stop the native battery listener * appropriately (and hopefully save onbattery life!). */Battery.onHasSubscribersChange = function() { // If we just registered the firsthandler, make sure native listener is started. if (this.numHandlers === 1 && handlers()=== 1) { exec(battery._status, battery._error,"Battery", "start", []); } else if (handlers() === 0) { exec(null, null, "Battery","stop", []); }};
在函数里执行exec函数来完成插件与本地原生代码的连接。使用exec函数调用原生代码,然后原始代码返回结果,在这个例子中,原始代码保持了返回数据的通道,使得,原生代码一检测到电量变化,就立马使用这个保持的通道,来告知插件电量的变化,,然后插件激发自定义消息,。这样用户界面就会收到电量变化的事件。
本文仅提供思路与方法,具体定制自定义消息,需要深入阅读并测试这个插件的源代码。
插件源码地址:https://github.com/apache/cordova-plugin-battery-status
新闻热点
疑难解答