改變 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)存泄露
下列這段簡(jiǎn)單的代碼,居然可能會(huì)出現(xiàn)內(nèi)存泄露!
Toast.makeText(MainActivity.this, "Hello", Toast.LENGTH_SHORT).show();
原因在于:如果在 Toast 消失之前,Toast 持有了當(dāng)前 Activity,而此時(shí),用戶點(diǎn)擊了返回鍵,導(dǎo)致 Activity 無(wú)法被 GC 銷毀, 這個(gè) Activity 就引起了內(nèi)存泄露.
一個(gè)很簡(jiǎn)單的解決方法:所有只要和布局無(wú)關(guān)的 Context 都可以傳入 ApplicationContext
, 此避免內(nèi)存泄露的方法同樣試用于其他需要傳入 Context 的地方。就像這樣:
Toast toast = Toast.makeText(getApplicationContext(), "Gravity", Toast.LENGTH_SHORT);
顯示時(shí)間只有 LENGTH_SHORT, LENGTH_LONG 可以選擇
frameworks/base/services/java/com/android/server/NotificationManagerService.java
查看源碼可以發(fā)現(xiàn),沒(méi)有其他顯示時(shí)間長(zhǎng)度可以選擇。
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() 方法其實(shí)是入隊(duì)操作
/**
* 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
中的入隊(duì)方法
enqueueToast
發(fā)現(xiàn)非系統(tǒng)應(yīng)用是有最大總數(shù)限制的,而系統(tǒng)應(yīng)用沒(méi)有
// 非系統(tǒng)Toast,每個(gè)pkg在當(dāng)前mToastQueue中Toast有總數(shù)限制,不能超過(guò)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;
}
}
}
}