在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;
注册返回键处理动作,我们自己对返回键的处理需要在这里实现了,注意返回的是一个函数,调用这个函数将取消本次事件注册。
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- $backButtonActions: {},
- registerBackButtonAction: function(fn, priority, actionId) {
-
- if(!self._hasBackButtonHandler) {
-
- 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 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 {
-
- }
- });
- }
-
-
- if ($location.path() == '/home' ) {
- showConfirm();
- } else if ($rootScope.$viewHistory.backView ) {
- console.log('currentView:', $rootScope.$viewHistory.currentView);
-
- $rootScope.$viewHistory.backView.go();
- } else {
-
- showConfirm();
- }
-
- return false;
- }, 101);
-
- }])