標籤:
在HybridApp移動跨平台開發中,android平台會遇到一些比較特殊並難以解決的問題,這些問題在原生應用開發中很easy, Android的返回鍵處理就是問題之一,假如我們要實現一個在很多App中都有的在首頁按返回鍵彈出對話方塊提示使用者退出應用的功能,在原生應用開發中是很容易的,只要在onKeyUp事件裡面對返回鍵事件進行處理就可以了。按2次返回鍵退出應用的Java代碼如下:
private long exitTime = 0;@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) { if(keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN){ if((System.currentTimeMillis()-exitTime) > 2000){ Toast.makeText(getApplicationContext(), "再按一次退出程式", Toast.LENGTH_SHORT).show(); exitTime = System.currentTimeMillis(); } else { finish(); System.exit(0); } return true; } return super.onKeyDown(keyCode, event);}
但在使用了Cordova的HTML5應用程式中,事情就沒有這麼簡單了,首先WebView接管了返回鍵的事件,你無法在Java層處理返回鍵或者說不是那麼容易,除非改Cordova架構的代碼,但這樣顯然是不合適的,會帶來維護問題,也不符合一般的開發規範。即使我們可以修改Cordova源碼,同時處理好按返回鍵Webview回退上一頁和在首頁時彈出處理提示,也是很困難的。
在深入分析ionic架構源碼,在與ionic論壇的國外開發人員交流後,終於找到了一個比較後的解決方案。Ionic作為目前國外比較活躍的HybridApp移動開發架構,對Android平台的返回鍵的處理是有比較合理的解決方案的。ionic架構對android返回鍵處理的源碼如下:
返回鍵優先順序定義,主要用途是返回鍵行為的優先順序定義,例如當有彈出框時(優先順序400),按返回鍵取消彈出框,不回退頁面(優先順序100)
var PLATFORM_BACK_BUTTON_PRIORITY_VIEW = 100;var PLATFORM_BACK_BUTTON_PRIORITY_SIDE_MENU = 150;var PLATFORM_BACK_BUTTON_PRIORITY_MODAL = 200;var PLATFORM_BACK_BUTTON_PRIORITY_ACTION_SHEET = 300;var PLATFORM_BACK_BUTTON_PRIORITY_POPUP = 400;var PLATFORM_BACK_BUTTON_PRIORITY_LOADING = 500;
註冊返回鍵處理動作,我們自己對返回鍵的處理需要在這裡實現了,注意返回的是一個函數,調用這個函數將取消本次事件註冊。
/** * @ngdoc method * @name $ionicPlatform#registerBackButtonAction * @description * Register a hardware back button action. Only one action will execute * when the back button is clicked, so this method decides which of * the registered back button actions has the highest priority. * * For example, if an actionsheet is showing, the back button should * close the actionsheet, but it should not also go back a page view * or close a modal which may be open. * * @param {function} callback Called when the back button is pressed, * if this listener is the highest priority. * @param {number} priority Only the highest priority will execute. * @param {*=} actionId The id to assign this action. Default: a * random unique id. * @returns {function} A function that, when called, will deregister * this backButtonAction. */ $backButtonActions: {}, registerBackButtonAction: function(fn, priority, actionId) { if(!self._hasBackButtonHandler) { // add a back button listener if one hasn‘t been setup yet self.$backButtonActions = {}; self.onHardwareBackButton(self.hardwareBackButtonClick); self._hasBackButtonHandler = true; } var action = { id: (actionId ? actionId : ionic.Utils.nextUid()), priority: (priority ? priority : 0), fn: fn }; self.$backButtonActions[action.id] = action; // return a function to de-register this back button action return function() { delete self.$backButtonActions[action.id]; }; },
回到我們剛開始提出的問題,在首頁增加按返回鍵提出退出應用,在其它頁面正常返回上個頁面,只要註冊一個處理事件就可以了,代碼如下:
.run([‘$rootScope‘, ‘$ionicLoading‘, ‘$httpBackend‘, ‘$ionicLoading‘, ‘wxConfigService‘, ‘CurrentUserService‘, ‘$ionicPlatform‘, ‘$ionicPopup‘, ‘$location‘, ‘$ionicHistory‘, function($rootScope, $ionicLoading, $httpBackend, $ionicLoading, wxConfigService, CurrentUserService, $ionicPlatform, $ionicPopup, $location, $ionicHistory) { //首頁面顯示退出提示框 $ionicPlatform.registerBackButtonAction(function(e) { e.preventDefault(); function showConfirm() { var confirmPopup = $ionicPopup.confirm({ title: ‘<strong>退出應用?</strong>‘, template: ‘你確定要退出應用嗎?‘, okText: ‘退出‘, cancelText: ‘取消‘ }); confirmPopup.then(function(res) { if (res) { ionic.Platform.exitApp(); } else { // Don‘t close } }); } // Is there a page to go back to? if ($location.path() == ‘/homePage‘ || $location.path() == ‘/butlerPage‘ || $location.path() == ‘/valueAddedGoods‘ || $location.path() == ‘/myPage‘) { showConfirm(); } else { $ionicHistory.goBack(); } return false; }, 101); }])
如下:
ionic架構對Android返回鍵的處理