在Toast 类中,Toast.makeText() 是一个静态method。当您调用此方法时,将创建一个新的Toast 对象,并将您传递的Context 保存在其中,并使用系统的默认布局创建一个附加到您的Toast 对象的view,并且还设置了重力管理您的 toast 在屏幕上的显示位置。
您的toast 由系统服务显示。此服务维护要显示的toast messages 的queue,并使用自己的Thread 显示它们。当您在toast object 上调用show() 时,它会将您的toast 排入系统服务的消息队列中。因此,当您的activity 在创建20 toast 后被销毁时,系统服务已经开始行动,并且它的message queue 中有消息要显示。通过在您的activity(销毁时)上按后按,系统不能断定您可能不打算显示剩余的 toast 消息。只有当你从内存中清除你的应用程序时,系统才能自信地推断它不再需要从你的应用程序中显示toast message。
更多信息可以查看Toast class的源代码。我为你包括了相关的方法。顺便说一句,好问题??
Toast.makeText 的实现
/**
* Make a standard toast to display using the specified looper.
* If looper is null, Looper.myLooper() is used.
* @hide
*/
public static Toast makeText(@NonNull Context context, @Nullable Looper looper,
@NonNull CharSequence text, @Duration int duration) {
Toast result = new Toast(context, looper);
LayoutInflater inflate = (LayoutInflater)
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflate.inflate(com.android.internal.R.layout.transient_notification, null);
TextView tv = (TextView)v.findViewById(com.android.internal.R.id.message);
tv.setText(text);
result.mNextView = v;
result.mDuration = duration;
return result;
}
创建新的 Toast:
/**
* Constructs an empty Toast object. If looper is null, Looper.myLooper() is used.
* @hide
*/
public Toast(@NonNull Context context, @Nullable Looper looper) {
mContext = context; // your passed `context` is saved.
mTN = new TN(context.getPackageName(), looper);
mTN.mY = context.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.toast_y_offset);
mTN.mGravity = context.getResources().getInteger(
com.android.internal.R.integer.config_toastDefaultGravity);
}
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;
final int displayId = mContext.getDisplayId();
try {
service.enqueueToast(pkg, tn, mDuration, displayId);
} catch (RemoteException e) {
// Empty
}
}