Toast简介
官方介绍:A toast provides simple feedback about an operation in a small popup. It only fills the amount of space required for the message and the current activity remains visible and interactive. For example, navigating away from an email before you send it triggers a "Draft saved" toast to let you know that you can continue editing later. Toasts automatically disappear after a timeout.
Toast使用
Toast可能是Android使用最多的一个控件了,通常在程序中使用Toast的方式就是一行代码:
Toast类中提供了setView方法,可以自定义显示的视图。
布局文件toast_layout_root.xml内容;
Toast源码解析
Toast的源码分析,主要是三个入口,第一是Toast的构造,第二是Toast的显示,第三是Toast的消失
1、makeText方法
makeText的代码其实和自定义Toast的代码差不多,inflate一布局,设置显示的text和duration,其中布局对应的transient_notification.xml,源码位于:frameworks\base\core\res\layout\transient_notification.xml
系统Toast的布局文件非常简单,就是在垂直布局的LinearLayout里放置了一个TextView。
2、show
从show方法可以看出里面有两个新类INotificationManager和TN,tn是由mTN赋值过来的,mTN的实现在Toast的构造函数中,源码如下:
接下来,我们就从TN类的源码出发,探寻TN的作用。TN类继承自ITransientNotification.Stub,ITransientNotification.aidl,用于进程间通信,源码位于frameworks\base\core\java\android\app\ITransientNotification.aidl,TN源码如下
看下ITransientNotification.aidl ,就两个方法,如下:
具体实现就在TN类,其他进程回调TN类,来操作Toast的显示和消失:
这里可以看出Toast显示和消失用的Handler机制实现的。
INotificationManager调用了getService,如下:
得到INotificationManager服务,再调用enqueueToast方法,参数有三个,包名,TN,时间。INofiticationManager接口的具体实现类是NotificationManagerService类,源码位置:frameworks\base\services\core\java\com\android\server\notification\NotificationManagerService.java
enqueueToast将Toast加入队列,用来显示Toast,队列最大数50
判断是否系统的Toast,源码:
判断Toast是否在队列当中,源码:
设置该Toast为前台进程,源码:
直接显示Toast,源码:
从enqueueToast方法可知,先判断是不是系统和合法的Toast,然后判断是否在ToastQueue(这里解释了很多Toast,是一个个显示的),如果存在,只需要更新Toast显示的时间,如果不在,就直接显示,回调给TN类。到这里,知道了Toast是如何显示的。还没有结束,继续追踪mHandler,来到WorkerHandler :
到这里,知道了Toast是如何消失的。Toast核心代码显示和消失源码分析完成。
总结
Toast代码调用只有一行,了解这行代码的背后,有个ToastQueue,进入队列之前,会做一些合法性判断,使用进程间通信进行回调,Handler机制显示和消失。