首页 > 学院 > 开发设计 > 正文

Cordova插件开发之自定义消息事件addEventListener,fireWindowEvent

2019-11-09 15:17:08
字体:
来源:转载
供稿:网友

关于在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


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表