簡體   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