日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Toast弹不出来之谜

發布時間:2025/3/21 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Toast弹不出来之谜 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

今天早上測試應用的時候,忽然發現Toast彈不出來了,我用的華為測試機,以為是通知權限被關了,后來發現是開著的,這就納了悶了,這個Toast工具類用了好長時間了,后來發現這Toast原來還能這樣...

正文

以前工具類是這個樣子的(華為的通知權限放在了其他的地方)

final public class ToastUtil {private static Toast toast;//單例的toast/*** 顯示Toast*/public static void showToast(int text) {showToast(App.getInstance().getResources().getString(text));}public static void showToast(String text) {if (toast == null)toast = Toast.makeText(App.getInstance(), text, Toast.LENGTH_SHORT);toast.setText(text);toast.show();} }

平時用的都是好好的,為什么不能用了呢?

然后我通過debug發現所有路徑都走了,說明是調用成功了,后來想起來,是不是子線程的問題,打印了一下線程信息:

Thread.currentThread().getName();

發現果然第一次調用沒有跑在主線程中,這就尷尬了,在子線程中創建,并show()竟然沒有報錯,而且子線程創建的在主線程調用show()也沒有報錯,只是不顯示

到show()的源碼中發現,被try了..

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

修改方法

在創建和show的時候可以判斷是否是主線程,如果不是就放到主線程中就ok了

修改后的代碼,嗯,這樣就可以了(雖然有強迫癥看到這代碼很不爽,但是首先得能用)

final public class ToastUtil {private static Toast toast;//單例的toast/*** 顯示Toast*/public static void showToast(int text) {showToast(App.getInstance().getResources().getString(text));}public static void showToast(final String text) {if (toast == null) {//AppManager.getAppManager().currentActivity()是使用工具類獲取當前Activity對象的方法AppManager.getAppManager().currentActivity().runOnUiThread(new Runnable() {@Overridepublic void run() {toast = Toast.makeText(App.getInstance(), text, Toast.LENGTH_SHORT);toast.show();}});} else {//如果show()是在子線程觸發的,則在主線程來顯示if ("main".equals(Thread.currentThread().getName())) {toast.setText(text);//將文本設置給toasttoast.show();} else {AppManager.getAppManager().currentActivity().runOnUiThread(new Runnable() {@Overridepublic void run() {toast.setText(text);//將文本設置給toasttoast.show();}});}}} }

ps:近些天看到了一個類似的情況,比我分析的源碼更多:懷疑人生,主線程修改UI也會崩潰?

擴展

如果你因為某些情況,真的要在某個(注意是某個)子線程中彈出toast,可以使用以下方法在子線程開一個loop,這樣就可以彈toast了(當然你要自己知道后果,具體百度):

thread {Looper.prepare()Toast.makeText(context, "123", Toast.LENGTH_LONG).show()Looper.loop()}

如果遇到了連續彈toast后,導致后續一段時間彈不出toast,可以使用以下方法?,效果看起來一樣,只不過每次調用都是使用的新toast對象:

//將這兩行代碼toast.setText(text);//將文本設置給toasttoast.show(); 改為:toast.cancel()toast = Toast.makeText(app, text, Toast.LENGTH_LONG)toast.show()

end

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的Toast弹不出来之谜的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。