Android Toast时序管理

家可以看到:在调用 callback.show 方法之后又调用了个 scheduleTimeoutLocked 方法:

record.callback.show(record.token);//通知进程显示scheduleTimeoutLocked(record);//超时监听消息

而这个方法就是用于管理 Toast 时序:

private void scheduleTimeoutLocked(ToastRecord r)
    {
        mHandler.removeCallbacksAndMessages(r);
        Message m = Message.obtain(mHandler, MESSAGE_TIMEOUT, r);
        long delay = r.duration == Toast.LENGTH_LONG ? LONG_DELAY : SHORT_DELAY;
        mHandler.sendMessageDelayed(m, delay);
    }

scheduleTimeoutLocked 内部通过调用 HandlersendMessageDelayed 函数来实现定时调用,而这个 mHandler 对象的实现类,是一个叫做 WorkerHandler 的内部类:

private final class WorkerHandler extends Handler
    {
        @Override
        public void handleMessage(Message msg)
        {
            switch (msg.what)
            {
                case MESSAGE_TIMEOUT:
                    handleTimeout((ToastRecord)msg.obj);
                    break;
                ....
            }
    } 
    private void handleTimeout(ToastRecord record)
    {
        synchronized (mToastQueue) {
            int index = indexOfToastLocked(record.pkg, record.callback);
            if (index >= 0) {
                cancelToastLocked(index);
            }
        }
    }

WorkerHandler 处理 MESSAGE_TIMEOUT 消息会调用 handleTimeout(ToastRecord) 函数,而 handleTimeout(ToastRecord) 函数经过搜索后,将调用cancelToastLocked 函数取消掉 Toast 的显示:

void cancelToastLocked(int index) {
        ToastRecord record = mToastQueue.get(index);
            ....
            record.callback.hide();//远程调用hide,通知客户端隐藏窗口
            ....
 
        ToastRecord lastToast = mToastQueue.remove(index);
        mWindowManagerInternal.removeWindowToken(lastToast.token, true);
        //将给 Toast 生成的窗口 Token 从 WMS 服务中删除
        ...

cancelToastLocked 函数将做以下两件事:

  1. 远程调用 ITransientNotification.hide 方法,通知客户端隐藏窗口
  2. 将给 Toast 生成的窗口 TokenWMS 服务中删除

上面我们就从源码的角度分析了一个Toast的显示和隐藏,我们不妨再来捋一下思路,Toast 的显示和隐藏大致分成以下核心步骤:

  1. Toast 调用 show 方法的时候 ,实际上是将自己纳入到 NotificationManagerToast 管理中去,期间传递了一个本地的 TN 类型或者是ITransientNotification.StubBinder 对象
  2. NotificationManager 收到 Toast 的显示请求后,将生成一个 Binder 对象,将它作为一个窗口的 token 添加到 WMS 对象,并且类型是 TOAST
  3. NotificationManager 将这个窗口 token 通过 ITransientNotificationshow 方法传递给远程的 TN 对象,并且抛出一个超时监听消息scheduleTimeoutLocked
  4. TN 对象收到消息以后将往 Handler 对象中 post 显示消息,然后调用显示处理函数将 Toast 中的 View 添加到了 WMS 管理中, Toast 窗口显示
  5. NotificationManagerWorkerHandler 收到 MESSAGE_TIMEOUT 消息, NotificationManager 远程调用进程隐藏 Toast 窗口,然后将窗口 tokenWMS中删除


 

  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

薛文旺

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值