您的位置:首页 > 编程语言 > Java开发

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

2017-11-01 16:00 573 查看
转自 Android系统原理与源码分析(1):利用Java反射技术阻止通过按钮关闭对话框

由于系统通过调用dismiss来关闭对话框,那么我们可以在dismiss方法上做点文章。在系统调用dismiss方法时会首先判断对话框是否已经关闭,如果对话框已经关闭了,就会退出dismiss方法而不再继续关闭对话框了。因此,我们可以欺骗一下系统,当调用dismiss方法时我们可以让系统以为对话框已经关闭(虽然对话框还没有关闭),这样dismiss方法就失效了,这样即使系统调用了dismiss方法也无法关闭对话框了。

下面让我们回到AlertDialog的源代码中,再继续跟踪到AlertDialog的父类Dialog的源代码中。找到dismissDialog方法。实际上,dismiss方法是通过dismissDialog方法来关闭对话框的,dismissDialog方法的代码如下:

private   void  dismissDialog() {
if  (mDecor  ==   null ) {
if  (Config.LOGV) Log.v(LOG_TAG,
" [Dialog] dismiss: already dismissed, ignore " );
return ;
}
if  ( ! mShowing) {
if  (Config.LOGV) Log.v(LOG_TAG,
" [Dialog] dismiss: not showing, ignore " );
return ;
}

mWindowManager.removeView(mDecor);

mDecor  =   null ;
mWindow.closeAllPanels();
onStop();
mShowing  =   false ;

sendDismissMessage();
}


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

try
{
Field field  =  dialog.getClass()
.getSuperclass().getDeclaredField(
" mShowing " );
field.setAccessible( true );
//   将mShowing变量设为false,表示对话框已关闭
field.set(dialog,  false );
dialog.dismiss();

}
catch  (Exception e)
{

}


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

从本文可以看出,虽然使用普通方法控制对话框的某些功能,但通过反射技术可以很容易地做到看似不可能完成的任务。当然,除了控制对话框的关闭功能外,还可以控制对话框其他的行为,剩下的就靠读者自己挖掘了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐