「Android Tips」Toast 的一些使用技巧

改變 Toast 的位置


Toast toast = Toast.makeText(this, "Gravity", Toast.LENGTH_SHORT);
toast.setGravity(Gravity.BOTTOM|Gravity.RIGHT, 0, 0);
toast.show();

自定義 Toast 的布局


LayoutInflater inflater = getLayoutInflater();
# 解析自定義布局,父布局傳入肯
View layout = inflater.inflate(R.layout.toast_layout, (ViewGroup) findViewById(R.id.toast_layout_root));
# 填充信息,比如設(shè)置文字,圖片等
TextView text = (TextView) layout.findViewById(R.id.text);
text.setText("This is a custom Toast.");
# 顯示 Toast
Toast toast = new Toast(getApplicationContext());
toast.setDuration(Toast.LENGTH_LONG);
toast.setView(layout);
toast.show();

避免內(nèi)存泄露


下列這段簡單的代碼,居然可能會出現(xiàn)內(nèi)存泄露!

Toast.makeText(MainActivity.this, "Hello", Toast.LENGTH_SHORT).show();

原因在于:如果在 Toast 消失之前,Toast 持有了當前 Activity,而此時,用戶點擊了返回鍵,導(dǎo)致 Activity 無法被 GC 銷毀, 這個 Activity 就引起了內(nèi)存泄露.

一個很簡單的解決方法:所有只要和布局無關(guān)的 Context 都可以傳入 ApplicationContext, 此避免內(nèi)存泄露的方法同樣試用于其他需要傳入 Context 的地方。就像這樣:

Toast toast = Toast.makeText(getApplicationContext(), "Gravity", Toast.LENGTH_SHORT);

顯示時間只有 LENGTH_SHORT, LENGTH_LONG 可以選擇


frameworks/base/services/java/com/android/server/NotificationManagerService.java 查看源碼可以發(fā)現(xiàn),沒有其他顯示時間長度可以選擇。

private static final int LONG_DELAY = 3500; // 3.5 seconds
private static final int SHORT_DELAY = 2000; // 2 seconds
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);
}

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
    }
}

普通應(yīng)用的 Toast 顯示數(shù)量是有限制的


查看
frameworks/base/services/java/com/android/server/NotificationManagerService.java 中的入隊方法
enqueueToast 發(fā)現(xiàn)非系統(tǒng)應(yīng)用是有最大總數(shù)限制的,而系統(tǒng)應(yīng)用沒有

// 非系統(tǒng)Toast,每個pkg在當前mToastQueue中Toast有總數(shù)限制,不能超過MAX_PACKAGE_NOTIFICATIONS
if (!isSystemToast) {
    int count = 0;
    final int N = mToastQueue.size();
    for (int i=0; i<N; i++) {
        final ToastRecord r = mToastQueue.get(i);
        if (r.pkg.equals(pkg)) {
            count++;
            if (count >= MAX_PACKAGE_NOTIFICATIONS) {
                Slog.e(TAG, "Package has already posted " + count + " toasts. Not showing more. Package=" + pkg);
                return;
            }
         }
     }
 }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容