關于在cordova的插件開發(fā)的做定義消息的功能沒有官方的介紹文章,但是官方有一個這樣的例子,就是電源狀態(tài)插件。我們通過學習這個插件的編寫來學習自定義消息。
這個插件的地址為:https://github.com/apache/cordova-plugin-battery-status
安裝方法為:cordova plugin add cordova-plugin-battery-status
使用方法是:在自己的js工程里執(zhí)行以下幾句話:
window.addEventListener("batterystatus", onBatteryStatus, false); function onBatteryStatus(status) { console.log("Level: " + status.level + " isPlugged: " + status.isPlugged);}分別是給工程添加插件自定義的消息事件,并指定消息響應函數(shù)
在我的測試例子中,使用了如下函數(shù)為兩個按鍵的響應函數(shù),一個訂閱消息,一個取消訂閱:
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
這里顯然就是典型的回調(diào)機制,就是在自己的工程里定制消息的響應回調(diào)函數(shù),然后當產(chǎn)生這個消息的話,回調(diào)函數(shù)就會被調(diào)用。
那么接下來看一下這個電池狀態(tài)插件是怎樣實現(xiàn)的。
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代碼和硬件本地代碼聯(lián)系起來。
整個插件的工作原理是:
1. 定義自定義消息
2. 調(diào)用端增加對自定義消息的接聽(addEventListener)
3. 本地產(chǎn)生消息,通過exec函數(shù)指定的回調(diào)函數(shù)來響應。,然后在相應函數(shù)里,激發(fā)自定義消息。(fireWindowEvent)
4. 接聽者收到消息和參數(shù)
其中自定義消息部分是:
// 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; }};
這里共定義了三條消息。格式參考以上格式,
當有人注冊這個自定義消息的時候會響應以下函數(shù):
/** * 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", []); }};
在函數(shù)里執(zhí)行exec函數(shù)來完成插件與本地原生代碼的連接。使用exec函數(shù)調(diào)用原生代碼,然后原始代碼返回結果,在這個例子中,原始代碼保持了返回數(shù)據(jù)的通道,使得,原生代碼一檢測到電量變化,就立馬使用這個保持的通道,來告知插件電量的變化,,然后插件激發(fā)自定義消息,。這樣用戶界面就會收到電量變化的事件。
本文僅提供思路與方法,具體定制自定義消息,需要深入閱讀并測試這個插件的源代碼。
插件源碼地址:https://github.com/apache/cordova-plugin-battery-status
新聞熱點
疑難解答