android 永不关闭toast
Toast信息提示框之所以在显示一定时间后会自动关闭,是因为在系统中有一个Toast队列;那么有些时候需要这个Toast信息提示框长时间显示,直到需要关闭它时通过代码来控制,而不是让系统自动来关闭Toast信息提示框
Toast信息提示框之所以在显示一定时间后会自动关闭,是因为在系统中有一个Toast队列。系统会依次从队列中取(出队列)一个Toast,并显示它。在显示一段时间后,再关闭,然后再显示下一个Toast信息提示框。直到Toast队列中所有Toast都显示完为止。那么有些时候需要这个Toast信息提示框长时间显示,直到需要关闭它时通过代码来控制,而不是让系统自动来关闭Toast信息提示框。不过这个要求对于Toast本身来说有些过分,因为Toast类并没有提供这个功能。虽然如此,但方法总比问题多。通过一些特殊的处理还是可以实现这个功能的,而且并不复杂。
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();
android 永不关闭toast的更多相关文章
- 在 uniGUI 中实现自动弹窗后延迟几秒关闭 — Toast 功能
在 uniGUI 中实现自动弹窗后延迟几秒关闭 — Toast 功能. uniGUI 的客户端使用 EXTJS 6 ,本就有 Toast 功能. 但UniGui 官方没有相应的控件,我们如何使用 EX ...
- Android弹出Toast工具类总结
Android弹出Toast工具类总结,包括系统自带的,也包括自定义的. public class ToastUtil { public ToastUtil() { } public static T ...
- Android之提示Toast
步骤: 设置监听事件步骤1.事件源,如按键 btn_simple2.事件 OnClick3.监听器new OnClickListener3.绑定事件源与事件 setOnClickListener(ne ...
- I.MX6 Android 永不休眠
/************************************************************************* * I.MX6 Android 永不休眠 * 说明 ...
- Android自己定义Toast
一.引言 在开发的过程中你会发现Android自身的Toast提示有很多限制,比方我想自己定义Toast的动画.自己定义一个美观的View显示在Toast中.很多其它的是让Toast显示指定的时长等等 ...
- Android开发关闭虚拟按钮、底部导航条
在Android开发中,遇到了一系列大大小小的问题,其中一个就是屏蔽底部实体键,我找了很多的博客也尝试了许许多多的方法,但始终不能屏蔽 HOME键,后来看见一篇博客说在Android 4.0以后,屏蔽 ...
- Android中的Toast重复显示的问题
Toast是Android中用来显示信息的一种机制,和Dialog不一样的是,Toast是没有焦点,而且Toast显示的时间有限,过一定的时间就会自动消失. Toast一般用来提示用户的误操作.但是如 ...
- Android开发之Toast
第一次在博客园发布文章,就把我刚弄明白的关于Android开发中的提示设置,分享给大家. Toast是Android中经常用到的一个方法,用于简单的用户提示,经过摸索我发现了Toast的两种使用方式, ...
- 使用android ProgressBar和Toast生成一个界面
首先我需要这样一个界面 这个界面是在使用AudioManager.adjustStreamVolume(int streamType, int direction, int flags)显示出来的,记 ...
随机推荐
- 实现一个 Variant
很多时候我们希望能够用一个变量来保存和操作不同类型的数据(比如解析文本创建 AST 时保存不同类型的结点),这种需求可以通过继承来满足,但继承意味着得使用指针或引用,除了麻烦和可能引起的效率问题,该做 ...
- WCF学习日记
图书馆借阅了<WCF高级编程>,从6.11开始学习wcf,希望尽快熟悉原理和编程模型以及常用编程方法. WCF是一个平台,也是一个框架,从Net.3.0 就在Net framewo ...
- STL中的set/multiset小结
(1)使用set/multiset之前必须包含头文件<set>:#include<set> (2)namespace std{ template <class T, cl ...
- NPM使用详解(下)
NPM使用详解(下) *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !impo ...
- [python]闭包到底是什么鬼?
这些东西是我在慕课网,廖雪峰大神的python课中学到的.自己写成笔记的形式分享给大家. 先来看一段代码: def f1(x): return x*x def new_fn(f): def fn(j) ...
- android程序---->android多线程下载(一)
多线程下载是加快下载速度的一种方式,通过开启多个线程去执行一个任务,可以使任务的执行速度变快.多线程的任务下载时常都会使用得到断点续传下载,就是我们在一次下载未结束时退出下载,第二次下载时会接着第一次 ...
- SQL Server 存储(8/8):理解数据文件结构
这段时间谈了很多页,现在我们可以看下这些页在数据文件里是如何组织的. 我们都已经知道,SQL Server把数据文件分成8k的页,页是IO的最小操作单位.SQL Server把数据文件里的第1页标记为 ...
- 阅读Nosql代码有感
这一年总得来说,读书的时间不多.一是因为时间啥关系,这一年一直在跟着项目走,或者被项目牵着走,几乎所有的时间和精力全部被拴在几个项目上:不过所幸今年创业失败,又回去上班了,时间相对空余了一些. 双十一 ...
- DZNEmptyDataSet,优秀的空白页或者出错页封装
简介 项目主页:https://github.com/dzenbot/DZNEmptyDataSet 提示:主要用于UITableView和UICollectionView,也可以用于UIScroll ...
- Sprint回顾
1.回顾组织 主题:“我们下次怎么样才能更加认真对待?” 时间:设定为1至2个小时. 参与者:整个团队. 场所:能够在不受干扰的情况下讨论. 秘书:指定某人当秘书,筹备.记录.整理. 2.回顾流程 ...