繁体   English   中英

为什么即使应用程序调用了 onDestroy(),Toast 仍然显示?

[英]Why Toast keeps showing even when the app called onDestroy()?

假设我在onCreate()中有这段代码

   for (int i = 0; i < 20; i++) {
        Toast.makeText(MainActivity.this, "Toast "+i, Toast.LENGTH_SHORT).show();
    }

当我启动应用程序时,Toasts 开始弹出。

现在,当我按下后退按钮时(比如说在 Toast 5 之后)。 onDestroy()被调用,应用程序被关闭。

但是我仍然可以看到 Toast 弹出,直到它达到 20 或者我从 memory 清除应用程序。

问题:

为什么我的代码用完了应用程序?

我已经给出了我的活动的上下文,那么它不应该在活动被破坏后立即停止吗?

这里的context不重要吗?

如果您链接任何文档,将会很有帮助。

Toast class 中, Toast.makeText()是一个 static method 当您调用此方法时,将创建一个新的Toast object 并将您传递的Context保存在其中,系统的默认布局用于创建一个附加到您的Toast object 的view ,并且还设置了重力以管理您的toast在屏幕上的位置显示。

您的toast由系统服务显示。 此服务维护要显示的toast messages queue ,并使用自己的Thread显示它们。 当您在toast object上调用show()时,它会将您的toast排入系统服务的消息队列中。 因此,当您的activity在创建20 toast后被销毁时,系统服务已经开始行动,并且它的message queue中有消息要显示。 通过对您的activity (销毁)进行后按,系统无法得出结论,您可能不打算显示剩余的 toast 消息。 只有当您从 memory 清除您的应用程序时,系统才能自信地推断它不再需要从您的应用程序显示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;
}

创建新的吐司:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM