【Android】Toast對應的LENGTH_SHORT和LENGTH_LONG分別是多長時間
阿新 • • 發佈:2020-12-03
Toast對應的LENGTH_SHORT和LENGTH_LONG分別是多長時間?
我們經常使用Toast,通過LENGTH_SHORT
或者LENGTH_LONG
,但沒特別注意具體顯示多長時間。今天突然看了一下Toast.java
原始碼(android-28
),發現程式碼定義如下:
/** * Show the view or text notification for a short period of time. This time * could be user-definable. This is the default. * @see #setDuration */ public static final int LENGTH_SHORT = 0; /** * Show the view or text notification for a long period of time. This time * could be user-definable. * @see #setDuration */ public static final int LENGTH_LONG = 1;
大寫懵逼,0
和1
是什麼鬼?
繼續往下找……
makeText
方法沒有什麼實質性呼叫,主要是解析佈局,設定引數,
直接看Toast
的show
方法,
/** * Show the view for the specified duration. */ public void show() { if (mNextView == null) { throw new RuntimeException("setView must have been called"); } INotificationManager service = getService(); String pkg = mContext.getOpPackageName(); TN tn = mTN; tn.mNextView = mNextView; try { service.enqueueToast(pkg, tn, mDuration); } catch (RemoteException e) { // Empty } }
繼續跟,這裡通過getService()
拿到了NotivicationManagerService
的代理INotificationManager
,
static private INotificationManager getService() { if (sService != null) { return sService; } sService = INotificationManager.Stub.asInterface(ServiceManager.getService("notification")); return sService; }
然後呼叫了service.enqueueToast(pkg, tn, mDuration);
,直接看NotificationManagerService
的enqueueToast
方法,
@Override
public void enqueueToast(String pkg, ITransientNotification callback, int duration)
{
//...略...
synchronized (mToastQueue) {
//...略...
// If it's at index 0, it's the current toast. It doesn't matter if it's
// new or just been updated. Call back and tell it to show itself.
// If the callback fails, this will remove it from the list, so don't
// assume that it's valid after this.
if (index == 0) {
showNextToastLocked();
}
//...略...
}
}
重點關注這個方法showNextToastLocked()
,輾轉呼叫到scheduleDurationReachedLocked
方法,開始了toast
的顯示,繼續跟下去,真是柳暗花明又一村……
前邊是構建ToastRecord
,這裡通過Handler
進行顯示了
@GuardedBy("mToastQueue")
private void scheduleDurationReachedLocked(ToastRecord r)
{
mHandler.removeCallbacksAndMessages(r);
Message m = Message.obtain(mHandler, MESSAGE_DURATION_REACHED, r);
long delay = r.duration == Toast.LENGTH_LONG ? LONG_DELAY : SHORT_DELAY;
mHandler.sendMessageDelayed(m, delay);
}
終於發現了最終的duration
的真面目。
long delay = r.duration == Toast.LENGTH_LONG ? LONG_DELAY : SHORT_DELAY;
在NotificationManagerService.java
中定義,
static final int LONG_DELAY = PhoneWindowManager.TOAST_WINDOW_TIMEOUT;
static final int SHORT_DELAY = 2000; // 2 seconds
而LONG_DELAY
定義在PhoneWindowManager
中
/** Amount of time (in milliseconds) a toast window can be shown. */
public static final int TOAST_WINDOW_TIMEOUT = 3500; // 3.5 seconds
結果,不言而喻。