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

时间: 2024-10-17 10:19:16

android 永不关闭toast的相关文章

Android之提示Toast

步骤: 设置监听事件步骤1.事件源,如按键 btn_simple2.事件 OnClick3.监听器new OnClickListener3.绑定事件源与事件 setOnClickListener(new OnClickListener() {} 布局: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.c

Android弹出Toast工具类总结

Android弹出Toast工具类总结,包括系统自带的,也包括自定义的. public class ToastUtil { public ToastUtil() { } public static Toast showShortToast(Context context, String text) { Toast toast = Toast.makeText(context, text, 0); toast.show(); return toast; } public static Toast

Android之十一Toast 自定义Toast的实现方法,及其说明

Android Toast 自定义Toast的实现方法,及其说明 Android Toast用于在手机屏幕上向用户显示一条信息,一段时间后信息会自动消失.信息可以是简单的文本,也可以是复杂的图片及其他内容(显示一个view).  1.简单用法 Toast.makeText(midlet.getApplicationContext(), "用户名不能为空", Toast.LENGTH_LONG).show(); 2.自定义显示位置效果 代码 toast = Toast.makeText(

android打开关闭屏幕

打开和关闭手机屏幕方法: 1.关闭屏幕 //设备管理者 private DevicePolicyManager mDevicePolicyManager; //关屏组件 private ComponentName mCompName; onCreate() { mDevicePolicyManager = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE); // 申请权限 mCompName = new C

Android开发关闭虚拟按钮、底部导航条

在Android开发中,遇到了一系列大大小小的问题,其中一个就是屏蔽底部实体键,我找了很多的博客也尝试了许许多多的方法,但始终不能屏蔽 HOME键,后来看见一篇博客说在Android 4.0以后,屏蔽底部HOME键必须反编译,修改Android底部原生代码,于是我便放弃了.废话不多说,我先分享一个屏蔽Android虚拟按键的方法,以及最简单的屏蔽Android的Back按钮,适合所有版本(未测试,感觉是这样): 1. Android 屏蔽Back按键 只需要重写 onKeyDown 方法就可以了

Android中土司(Toast)的使用

 Android中Toast的使用 什么是土司(Toast)? Toast是Android系统提供的一种非常好的提示方式,在程序中可以使用它将一些短小的信息通知给用户,这些信息会在一段时间后自动消失,并且不会占用任何的屏幕空间. 下面我们通过代码来体验一下土司在Android中的使用 1 import android.app.Activity; 2 import android.content.Intent; 3 import android.os.Bundle; 4 import androi

android 开发之Toast

今天新学了几个方法,现在分享下 Toast 的用法. Toast的用法非常简单,首先介绍一下 Toast.Toast是我在写myClock的时候遇到的,发现这是个安卓系统提供的一种非常好的提醒方式,在程序中可以使用它将一些短小的信息通知给用户, 这些消息会在click一段时间后自动消失,并且不占用屏幕的空间.下面上代码: 第一:定义一个Toast的触法点,下面就实现一个button来做Toast触法点. activity_main.xml 1 <?xml version="1.0"

android系统 关闭应用

1.概述: 应用程序部署到手机上对应的进程有五种优先级:前台进程.可视进程.服务进程.后台进程.空进程. android系统中,默认情况下是不会把进程杀死掉的,这种做法的目的是:再次打开这个应用程序的时候可以快速的启动,节省时间. 但是这样做也带来了一个问题,有很多的应用程序都在后台留一个空进程,这样就会占据一些内存空间,影响手机的运行速度. 作为一个有责任感的程序员,我们要保证应用程序在结束时释放掉对应的进程. 2.关闭方式 第一种:首先获取当前进程的id,然后杀死该线程. //获取当前进程的

android 如何关闭来电号码归属地

MTK平台号码归属地分为两种:1.手机号码归属地:2.固话号码归属地: 手机号码归属地: 是MTK自己做的,关闭只需要关闭MTK_PHONE_NUMBER_GEODESCRIPTION这个option即可: 数据库文件所在路径为 alps/mediatek/external/geocoding/geocoding.db: 仅支持汉语. 固话号码归属地: 是Google Android系统自带的,关闭需要注解掉Google的原始code: 数据库文件所在路径为 alps/external/libp