有时候,不能让用户进行回退操作,如何处理?

查看返回键触发了哪些方法。在打开程序后把这个方法禁止了。
问题:程序在后台驻留,这样就会出现,其他时候也不能使用回退按钮。如何处理,在onpase()时方法失效。
方案一:
 //重载onBackPressed
@Override
public void onBackPressed() {
// TODO Auto-generated method stub
//super.onBackPressed();
}

查看Adroid源码 onBackPressed ()源码:

     public void onBackPressed() {
finish();
}

重写这个方法会不会有什么问题呢?他执行一个finish();方法对其本身应该没什么问题,那么调用出呢?

下面是Activity中调用的两处:
Adroid源码调用1:
     public boolean onKeyDown(int keyCode, KeyEvent event) {
//当按钮等于KEYCODE_BACK时执行下面方法,KEYCODE_BACK这个就是返回键
if (keyCode == KeyEvent.KEYCODE_BACK) {
//检测版本号 ECLAIR 值为:public static final int ECLAIR = 5;
if (getApplicationInfo().targetSdkVersion
>= Build.VERSION_CODES.ECLAIR) {
//当大于5是执行
/**startTracking()解释:调用onKeyUp()方法。
Call this during Callback.onKeyDown to have the system track the key through its final up (possibly including a long press). Note that only one key can be tracked at a time -- if another key down event is received while a previous one is being tracked, tracking is stopped on the previous event.
*/
event.startTracking();
} else {
onBackPressed();
}
return true;
}
}

Adroid源码调用2:

     public boolean onKeyUp(int keyCode, KeyEvent event) {
if (getApplicationInfo().targetSdkVersion
>= Build.VERSION_CODES.ECLAIR) {
if (keyCode == KeyEvent.KEYCODE_BACK && event.isTracking()
&& !event.isCanceled()) {
onBackPressed();
return true;
}
}
return false;
}

  到这里可以看出我们在onBackPressed()被调用处,都是在按下返回键的情况下,所以可以冲写onBackPressed方法,因为是被调用的,虽然不会出错,但是效率应该不高。

要不我们重写onKeyDown方法这样可行,直接拦截。
  @Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode==KeyEvent.KEYCODE_BACK) {
Toast.makeText(getApplicationContext(), "back press", Toast.LENGTH_LONG).show();
return false; // Disable back button..............
}

但是会如果在按钮处直接拦截,效果应该会高一些,这样就不会触发上面这两个方法了。

于是乎我们继续向上寻找。
细心的朋友可能发现onBackPressed()调用了finish()方法,所以干脆我们重写它吧。
方案二:重载finish函数:
查看Android的 finish()源码:
 public void finish() {
if (mParent == null) {
int resultCode;
Intent resultData;
synchronized (this) {
resultCode = mResultCode;
resultData = mResultData;
}
if (Config.LOGV) Log.v(TAG, "Finishing self: token=" + mToken);
try {
if (ActivityManagerNative.getDefault()
.finishActivity(mToken, resultCode, resultData)) {
mFinished = true;
}
} catch (RemoteException e) {
// Empty
}
} else {
mParent.finishFromChild(this);
}
}

查看Android源码中调用它的方法:

     /**
* This is called when a child activity of this one calls its
* {@link #finish} method. The default implementation simply calls
* finish() on this activity (the parent), finishing the entire group.
*
* @param child The activity making the call.
*
* @see #finish
*/
public void finishFromChild(Activity child) {
finish();
}

从说明中我们知道这个方法是在子Activity结束时调用的这个方法,所以不行,如果我们要重写,需要进行判断拿到的键值。效率不高。

继续寻找,看看哪里执行了调用方法按键吧。
方案三:重写keyevent方法 大括号里加上return true 这样就禁用父类方法达到禁止返回键的目的 
Android源码中找来找去找到了这个:
  /**
* Called to process key events. You can override this to intercept all
* key events before they are dispatched to the window. Be sure to call
* this implementation for key events that should be handled normally.
*
* @param event The key event.
*
* @return boolean Return true if this event was consumed.
*/
public boolean dispatchKeyEvent(KeyEvent event) {
onUserInteraction();
Window win = getWindow();
if (win.superDispatchKeyEvent(event)) {
return true;
}
View decor = mDecor;
if (decor == null) decor = win.getDecorView();
return event.dispatch(this, decor != null
? decor.getKeyDispatcherState() : null, this);
}

就是在按钮触发的事件,当然是Activity中的。到此我们发现我们找到地方了,按钮进入后第一个处理的地方,再次我们重写这个方法就OK了。

 @Override

 public boolean dispatchKeyEvent(KeyEvent event) {

 if (event.getKeyCode() == KeyEvent.KEYCODE_BACK)
{ return true; } return super.dispatchKeyEvent(event); }

Adroid学习之 从源码角度分析-禁止使用回退按钮方案的更多相关文章

  1. 源码角度分析-newFixedThreadPool线程池导致的内存飙升问题

    前言 使用无界队列的线程池会导致内存飙升吗?面试官经常会问这个问题,本文将基于源码,去分析newFixedThreadPool线程池导致的内存飙升问题,希望能加深大家的理解. (想自学习编程的小伙伴请 ...

  2. 从源码角度分析 MyBatis 工作原理

    一.MyBatis 完整示例 这里,我将以一个入门级的示例来演示 MyBatis 是如何工作的. 注:本文后面章节中的原理.源码部分也将基于这个示例来进行讲解.完整示例源码地址 1.1. 数据库准备 ...

  3. Android的Message Pool是什么——源码角度分析

    原文地址: http://blog.csdn.net/xplee0576/article/details/46875555 Android中,我们在线程之间通信传递通常采用Android的消息机制,而 ...

  4. 【原创】源码角度分析Android的消息机制系列(三)——ThreadLocal的工作原理

    ι 版权声明:本文为博主原创文章,未经博主允许不得转载. 先看Android源码(API24)中对ThreadLocal的定义: public class ThreadLocal<T> 即 ...

  5. 【原创】源码角度分析Android的消息机制系列(五)——Looper的工作原理

    ι 版权声明:本文为博主原创文章,未经博主允许不得转载. Looper在Android的消息机制中就是用来进行消息循环的.它会不停地循环,去MessageQueue中查看是否有新消息,如果有消息就立刻 ...

  6. 从源码角度分析 Kotlin by lazy 的实现

    by lazy 的作用 延迟属性(lazy properties) 是 Kotlin 标准库中的标准委托之一,可以通过 by lazy 来实现. 其中,lazy() 是一个函数,可以接受一个 Lamb ...

  7. Java面试题 从源码角度分析HashSet实现原理?

    面试官:请问HashSet有哪些特点? 应聘者:HashSet实现自set接口,set集合中元素无序且不能重复: 面试官:那么HashSet 如何保证元素不重复? 应聘者:因为HashSet底层是基于 ...

  8. 【原创】源码角度分析Android的消息机制系列(六)——Handler的工作原理

    ι 版权声明:本文为博主原创文章,未经博主允许不得转载. 先看Handler的定义: /** * A Handler allows you to send and process {@link Mes ...

  9. 【原创】源码角度分析Android的消息机制系列(四)——MessageQueue的工作原理

    ι 版权声明:本文为博主原创文章,未经博主允许不得转载. MessageQueue,主要包含2个操作:插入和读取.读取操作会伴随着删除操作,插入和读取对应的方法分别为enqueueMessage和ne ...

随机推荐

  1. C++指向常量的指针和常指针

    C++指向常量的指针和常指针 指向常量的指针 通常情况下,可以通过指针去修改指针指向的内容.但是在某些情况下,只希望通过指针去访问指针指向的内容,不想修改.比如只想通过树根结点的指针去遍历输出树中所有 ...

  2. MONO 如何打包 .NET程序独立运行(winform篇)

    .NET程序独立运行是指运行.NET的电脑上,不需要安装.NET框架. .NET程序集“独立运行”并非真正的独立,它是运行在mono运行时基础之上的.由于这个运行时可以独立存在,所以,我们不需要在目标 ...

  3. Matlab将三维变量分割为多个二维变量的方法

    最近在处理 Matlab 中的三维矩阵的时候,遇到了一个问题: 假如m 为 5*5*5的矩阵,如果以第三个维度为基础,分割为5个不同的矩阵 m1,m2,m3,m4,应该如何解决? 解决方法:eval函 ...

  4. 在内存中观察CRL托管内存及GC行为

    虽然看了一些书,还网络上的一些博文,不过对CRL托管内存的介绍都不是十分清楚,大部分都是一样的,如果再要了解细节就十分困难了. 所以借助winhex直接查看内存以证实书上的描述或更进一步揣摩CRL托管 ...

  5. WPF - 监听判断键盘组合键的按下

    对于键盘事件PreviewKeyDown.PreviewKeyUp.KeyDown.KeyUp,在其中检查当次事件是哪个按键触发的很简单,只需要判断KeyEventArgs类型的事件参数e的Key属性 ...

  6. Android--带你一点点封装项目 MVP+BaseActivity+Retrofit+Dagger+RxJava(三)

    1,这一篇博客是和大家一起来封装我们最后的Dagger2,其实之前也写过关于简单的Dagger2,这里是地址,完全没了解的同学可以先去看一下这篇,感谢很多小伙伴一直在耐心的等待这一篇 2,Dagger ...

  7. CentOs下安装PHP环境的步骤

    前言 在CentOs环境下安装php开发环境,需要首先安装一些源文件,然后使用yum命令直接安装即可,在Fedora 20 源中已经有了PHP的源,直接可以使用以下命令安装即可: # yum inst ...

  8. 快速排序 partition函数的所有版本比较

    partition函数是快排的核心部分 它的目的就是将数组划分为<=pivot和>pivot两部分,或者是<pivot和>=pivot 其实现方法大体有两种,单向扫描版本和双向 ...

  9. 1349: [Baltic2006]Squint

    1349: [Baltic2006]Squint Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 427  Solved: 248[Submit][Stat ...

  10. 《Django By Example》第九章 中文 翻译 (个人学习,渣翻)

    书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者@ucag 注:哈哈哈,第九章终于来啦 ...