Android开发技巧之永不关闭的Toast信息框(长时间显示而非系统关闭)

2016-02-19 10:33 49 1 收藏

今天图老师小编给大家展示的是Android开发技巧之永不关闭的Toast信息框(长时间显示而非系统关闭),精心挑选的内容希望大家多多支持、多多分享,喜欢就赶紧get哦!

【 tulaoshi.com - 编程语言 】

Toast信息提示框之所以在显示一定时间后会自动关闭,是因为在系统中有一个Toast队列。系统会依次从队列中取(出队列)一个Toast,并显示它。在显示一段时间后,再关闭,然后再显示下一个Toast信息提示框。直到Toast队列中所有Toast都显示完为止。那么有些时候需要这个Toast信息提示框长时间显示,直到需要关闭它时通过代码来控制,而不是让系统自动来关闭Toast信息提示框。不过这个要求对于Toast本身来说有些过分,因为Toast类并没有提供这个功能。虽然如此,但方法总比问题多。通过一些特殊的处理还是可以实现这个功能的,而且并不复杂。

从7.3.1节的内容可以知道,Toast信息提示框需要调用Toast.show方法来显示。下面来看一下show方法的源代码。
代码如下:

publicvoidshow(){
if(mNextView==null){
thrownewRuntimeException("setViewmusthavebeencalled");
}
INotificationManagerservice=getService();
Stringpkg=mContext.getPackageName();
TNtn=mTN;
try{
//将当前Toast加入到Toast队列
service.enqueueToast(pkg,tn,mDuration);
}catch(RemoteExceptione){
//Empty
}
}

show方法的代码并不复杂,可以很容易找到如下的代码。
代码如下:

service.enqueueToast(pkg,tn,mDuration);

从上面的代码可以很容易推断出它的功能是将当前的Toast加入到系统的Toast队列中。看到这里,各位读者应该想到。虽然show方法的表面功能是显示Toast信息提示框,但其实际的功能是将Toast加入到队列中,再由系统根据Toast队列来显示Toast信息提示框。那么我们经过更进一步地思考,可以大胆地做出一个初步的方案。既然系统的Toast队列可以显示Toast信息提示框,那么我们为什么不可以自己来显示它呢?这样不是可以自己来控制Toast的信息提示框的显示和关闭了吗!当然,这就不能再调用show方法来显示Toast信息提示框了(因为show方法会将Toast加入队列,这样我们就控制不了Toast了)。

既然初步方案已拟定,现在就来实施它。先在Toast类找一下还有没有其他的show方法。结果发现了一个TN类,该类是Toast的一个内嵌类。在TN类中有一个show方法。TN是ITransientNotification.Stub的子类。从ITransientNotification和TN类中的show方法初步推断(因为Transient的中文意思是“短暂的”)系统是从Toast队列中获得了Toast对象后,利用TN对象的show方法显示Toast,再利用TN.hide方法来关闭Toast。首先声明,这只是假设,我们还不知道这么做是否可行!当然,这也是科学研究的一般方法,先推断或假设,然后再证明推断或假设。

现在关键的一步是获得TN对象。遗憾的是TN被声明成private类型,外部无法访问。不过别着急。在Toast类中有一个mTN变量。虽然不是public变量,但仍然可以通过反射技术访问该变量。mTN变量会在创建Toast对象时初始化。因此,只要获得mTN变量,就获得了TN对象。下面的代码显示了一个永远不会自动关闭的Toast信息提示框。
代码如下:

//先创建一个Toast对象
Toasttoast=Toast.makeText(this,"永不消失的Toast",Toast.LENGTH_SHORT);
//设置Toast信息提示框显示的位置(在屏幕顶部水平居中显示)
toast.setGravity(Gravity.TOP|Gravity.CENTER_HORIZONTAL,0,0);
try
{
//从Toast对象中获得mTN变量
Fieldfield=toast.getClass().getDeclaredField("mTN");
field.setAccessible(true);
Objectobj=field.get(toast);
//TN对象中获得了show方法
Methodmethod=obj.getClass().getDeclaredMethod("show",null);
//调用show方法来显示Toast信息提示框
method.invoke(obj,null);
}
catch(Exceptione)
{
}

上面的代码中try{…}catch(…){…}语句中的代码是关键。先利用事先创建好的Toast对象获得了mTN变量。然后再利用反射技术获得了TN对象的show方法。
关闭Toast和显示Toast的方法类似,只是需要获得hide方法,代码如下:
代码如下:

try
{
//需要将前面代码中的obj变量变成类变量。这样在多个地方就都可以访问了
Methodmethod=obj.getClass().getDeclaredMethod("hide",null);
method.invoke(obj,null);
}
catch(Exceptione)
{
}

上面的代码已经很完美地实现了通过代码控制Toast信息提示框显示和关闭的功能。但如果想实现得更完美,可以在AndroidSDK源代码中找一个叫ITransientNotification.aidl的文件(该文件是AIDL服务定义文件,将在后面详细介绍),并在Android工程的src目录中建一个android.app包,将这个文件放到这个包中。然后ADT会自动在gen目录中生成了一个android.app包,包中有一个ITransientNotification.java文件。由于AndroidSDK自带的ItransientNotification接口属于内部资源,外部程序无法访问,因此,只能将从Toast对象中获得的mTN变量转换成刚才生成的ITransientNotification对象了。这样就不需要使反射技术获得show和hide方法了。经过改良的显示和关闭Toast信息提示框的代码如下:
代码如下:

ITransientNotificationnotification=(ITransientNotification)field.get(toast);
//显示Toast信息提示框
notification.show();
//关闭Toast信息提示框
notification.hide();

来源:https://www.tulaoshi.com/n/20160219/1595045.html

延伸阅读
贝贝信息声音如何关闭?   1)首先在手机桌面打开,然后点击右下方!   2)上面所示:进去以后点击下方,进去里面以后点击!   3)上面所示:最后在后方小框框把‘勾’去掉即可完成!
标签: 电脑入门
selinux是Linux的安全子系统,是一个强制访问控制安全模块,那么要如何关闭selinux安全子系统呢?下面图老师小编就给大家介绍下Linux关闭selinux的方法,一起来学习下吧。 1、首先我们可以用命令来查看selinux的状态 getenforce 这个命令可以查看到selinux的状态,当前可以看到是关闭状态的。 2、还有一个命令也可以查看出selinux的状态...
win7关闭右下角时间显示的方法   在我们多媒体课堂中许多用户在看老师做教程,但是有部分不爱学习的用户却顶着时间看,这样会造成学生的注意力分散,那么我们如何取消windows7系统右下角时间呢?今天河东图老师小编就专门针对此问题为大家提供了一个操作方法教程,无论是您在做课件、视频教程、多媒体授课时,或许能够用的到! ...
如何关闭WPS热点弹出框   1:我们打开WPS编辑,等一会就会显示热点框出来。 2:这时,你不要急于关点它。在右上角有一个设置的按钮。点击出来,选择以后不再弹出。然后再关点就行了。 WPS表格怎么利用下拉列表输入以及查询   1:现在WPS表格中输入好其他的内容,不要急着输入员工的职位之类的信息,选择员工职位...
安医生悬浮框如何关闭   1)安装并打开安医生,在主界面中点击选择。   2)将设为已关状态即可。

经验教程

866

收藏

25
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部