ionic框架对Android返回键的处理
在HybridApp移动跨平台开发中。android平台会遇到一些比較特殊并难以解决的问题,这些问题在原生应用开发中非常easy。 Android的返回键处理就是问题之中的一个。假如我们要实现一个在非常多App中都有的在主页按返回键弹出对话框提示用户退出应用的功能,在原生应用开发中是非常容易的,仅仅要在onKeyUp事件里面对返回键事件进行处理就能够了。按2次返回键退出应用的Java代码例如以下:
private long exitTime = 0; @Override public 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); }
但在使用了PhoneGap的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(['$ionicPlatform', '$ionicPopup','$rootScope','$location', function ($ionicPlatform, $ionicPopup, $rootScope, $location) { //主页面显示退出提示框 $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() == '/home' ) { showConfirm(); } else if ($rootScope.$viewHistory.backView ) { console.log('currentView:', $rootScope.$viewHistory.currentView); // Go back in history $rootScope.$viewHistory.backView.go(); } else { // This is the last page: Show confirmation popup showConfirm(); } return false; }, 101); }])