В Toast
классе, Toast.makeText()
является статическим method
. Когда вы вызываете этот метод, создается новый Toast
объект, и в нем сохраняется переданный вами Context
, а системный макет по умолчанию используется для создания view
, который присоединен к вашему Toast
объекту, и гравитация также устанавливается так, чтобыопределяет, где на экране будет отображаться ваш toast
.
Ваш toast
отображается системной службой. Эта служба поддерживает отображение queue
из toast messages
и отображает их, используя собственный Thread
. Когда вы звоните show()
на ваш toast object
, он помещает ваш toast
в очередь сообщений системной службы. Таким образом, когда ваш activity
уничтожается после создания 20 toast
, тогда системная служба уже вступила в действие, и в ее message queue
есть сообщения для отображения. При обратном нажатии на вашей системе activity
(при уничтожении) невозможно сделать вывод, что вы, возможно, не намереваетесь отображать оставшиеся всплывающие сообщения. Только когда вы удаляете свое приложение из памяти, система может уверенно сделать вывод, что ей больше не нужно отображать 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
}
}