利用Java反射技术阻止通过按钮关闭对话框

转载 2011年01月18日 12:54:00

众所周知,AlertDialog类用于显示对话框。关于AlertDialog的基本用法在这里就不详细介绍了,网上有很多,读者可以自己搜索。那么本文要介绍的是如何随心所欲地控制AlertDialog。
    现在我们来看看第一个需求:如果某个应用需要弹出一个对话框。当单击“确定“按钮时完成某些工作,如果这些工作失败,对话框不能关闭。而当成功完成工作后,则关闭对话框。当然,无论何程度情况,单击“取消”按钮都会关闭对话框。
    这个需求并不复杂,也并不过分(虽然我们可以自己弄个Activity来完成这个工作,也可在View上自己放按钮,但这显示有些大炮打蚊子了,如果对话框上只有一行文本,费这么多劲太不值了)。但使用过AlertDialog的读者都知道,无论单击的哪个按钮,无论按钮单击事件的执行情况如何,对话框是肯定要关闭的。也就是说,用户无法控制对话框的关闭动作。实际上,关闭对话框的动作已经在Android SDK写死了,并且未给使用者留有任何接口。但我的座右铭是“宇宙中没有什么是不能控制的”。
    既然要控制对放框的关闭行为,首先就得分析是哪些类、哪些代码使这个对话框关闭的。进入AlertDialog类的源代码。在AlertDialog中只定义了一个变量:mAlert。这个变量是AlertController类型。AlertController类是Android的内部类,在com.android.internal.app包中,无法通过普通的方式访问。也无法在Eclipse中通过按Ctrl键跟踪进源代码。但可以直接在Android源代码中找到AlertController.java。我们再回到AlertDialog类中。AlertDialog类实际上只是一个架子。象设置按钮、设置标题等工作都是由AlertController类完成的。因此,AlertController类才是关键。
    找到AlertController.java文件。打开后不要感到头晕哦,这个文件中的代码是很多地。不过这么多代码对本文的主题也没什么用处。下面就找一下控制按钮的代码。
    在AlertController类的开头就会看到如下的代码:

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->mHandler.obtainMessage(ButtonHandler.MSG_DISMISS_DIALOG, mDialogInterface)
                    .sendToTarget();

 

上面的代码并不是直接来关闭对话框的,而是通过一个Handler来处理,代码如下:


Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

我们可以看到,上面的类和AlertController中的ButtonHandler类很像,只是支掉了switch语句的最后一个case子句(用于调用dismiss方法)和相关的代码。
    下面我们就要为AlertController中的mHandler重新赋值。由于mHandler是private变量,因此,在这里需要使用Java的反射技术来为mHandler赋值。由于在AlertDialog类中的mAlert变量同样也是private,因此,也需要使用同样的反射技术来获得mAlert变量。代码如下:

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

上面的对话框很普通,单击哪个按钮都会关闭对话框。下面在调用show方法之前来修改一个mHandler变量的值,OK,下面我们就来见证奇迹的时刻。

我们发现,如果加上try   catch语句,单击对话框中的确定按钮不会关闭对话框(除非在代码中调用dismiss方法),单击取消按钮则会关闭对话框(因为调用了dismiss方法)。如果去了try…catch代码段,对话框又会恢复正常了。
    虽然上面的代码已经解决了问题,但需要编写的代码仍然比较多,为此,我们也可采用另外一种方法来阻止关闭对话框。这种方法不需要定义任何的类。
    这种方法需要用点技巧。由于系统通过调用dismiss来关闭对话框,那么我们可以在dismiss方法上做点文章。在系统调用dismiss方法时会首先判断对话框是否已经关闭,如果对话框已经关闭了,就会退出dismiss方法而不再继续关闭对话框了。因此,我们可以欺骗一下系统,当调用dismiss方法时我们可以让系统以为对话框已经关闭(虽然对话框还没有关闭),这样dismiss方法就失效了,这样即使系统调用了dismiss方法也无法关闭对话框了。
    下面让我们回到AlertDialog的源代码中,再继续跟踪到AlertDialog的父类Dialog的源代码中。找到dismissDialog方法。实际上,dismiss方法是通过dismissDialog方法来关闭对话框的,dismissDialog方法的代码如下:

该方法后面的代码不用管它,先看 if(!mShowing){ … } 这段代码。这个 mShowing 变量就是判断对话框是否已关闭的。因此,我们在代码中通过设置这个变量就可以使系统认为对话框已经关闭,就不再继续关闭对话框了。由于 mShowing 也是 private 变量,因此,也需要反射技术来设置这个变量。我们可以在对话框按钮的单击事件中设置 mShowing ,代码如下:

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

将上面的代码加到哪个按钮的单击事件代码中,哪个按钮就再也无法关闭对话框了。如果要关闭对话框,只需再将 mShowing 设为 true 即可。要注意的是,在一个按钮里设置了 mShowing 变量,也会影响另一个按钮的关闭对话框功能,因此,需要在每一个按钮的单击事件里都设置 mShowing 变量的值。

本文来自CSDN博客,转载请标明出处: http://blog.csdn.net/nokiaguy/archive/2010/07/27/5770263.aspx

安卓_利用Java反射技术阻止通过按钮关闭对话框

利用Java反射技术阻止通过按钮关闭对话框
  • wayne566
  • wayne566
  • 2017年11月01日 16:00
  • 102

六,关闭窗口X的控制,MFC 禁止对话框关闭按钮和Alt+F4

使得菜单项无效,以便它不能被选择,但不变灰使得菜单项有效,以便它能够被选择,并可从变灰的状态中恢复出来获取窗口菜单:      CMenu *pSysMenu = GetSystemMenu(FALS...
  • ljd_1986413
  • ljd_1986413
  • 2011年03月14日 14:45
  • 5184

Android系统原理与源码分析(1):利用Java反射技术阻止通过按钮关闭对话框

Android系统原理与源码分析(1):利用Java反射技术阻止通过按钮关闭对话框 分类: java Android 2010-07-27 23:33 16635人阅读 评论(3...
  • hedaogelaoshu
  • hedaogelaoshu
  • 2015年05月13日 16:57
  • 320

阻止对话框的正常关闭(AlertDialog)

对于正常的情况下,如果我
  • logicsboy
  • logicsboy
  • 2014年05月03日 18:08
  • 836

Android的AlertDialog点击确定后不关闭示例

首先先定义: private AlertDialog.Builder pwdBuilder; private AlertDialog pwdDialog;下面是创建builder和dialog /...
  • qq_34475058
  • qq_34475058
  • 2016年11月03日 17:05
  • 1335

QT5入门之5 - 确认退出对话框

#include QCloseEvent>//头文件记得添加 void closeEvent(QCloseEvent *event);//头文件中声明 void MainWindow::closeEv...
  • a379039233
  • a379039233
  • 2015年10月15日 11:43
  • 5813

Dialog点击确定不关闭窗口的方法

protected void keepDialogOpen(DialogInterface dialog) { // TODO Auto-generated method stub try { ...
  • zxwiiiii
  • zxwiiiii
  • 2017年06月29日 14:59
  • 216

如何关掉Win7下运行程序时候安全提示对话框

如何关掉Win7下运行程序时候安全提示对话框
  • daoming1112
  • daoming1112
  • 2017年08月17日 08:37
  • 93

点击按钮后弹出新的对话框

1. 在资源编辑框插入新的对话框,右键新对话框添加新类,注意Base Class要选CDialog:   2. 设置新Dialog属性,Style: Popup   3. 将新对话框的类的头文件添加...
  • phenixyf
  • phenixyf
  • 2014年12月05日 18:48
  • 1665

通过注册表配置弹出窗口阻止程序

转自:http://hejianlong.123.blog.163.com/blog/static/2671583920098411142467/ 注册表位置:[HKEY_CURRENT_USE...
  • baixiaohei09
  • baixiaohei09
  • 2016年10月31日 15:48
  • 1442
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:利用Java反射技术阻止通过按钮关闭对话框
举报原因:
原因补充:

(最多只允许输入30个字)