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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android进阶:六、在子线程中直接使用 Toast 及其原理

發布時間:2025/5/22 Android 65 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android进阶:六、在子线程中直接使用 Toast 及其原理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
最近因為個人原因,很久沒有更文章,感謝關注的小伙伴,望諒解!


一般我們都把Toast當做一個UI控件在主線程顯示。但是有時候非想在子線程中顯示Toast,就會使用Handler切換到主線程顯示。

但是子線程中真的不能直接顯示Toast嗎?

答案是:當然可以。

那應該怎么操作呢?在當前線程中先初始化一個Looper即可!

Looper.prepare(); Toast.makeText(getBaseContext(), "text", Toast.LENGTH_LONG).show(); Looper.loop(); 復制代碼

為什么在子線程中使用Toast需要初始一個Looper呢? 我們看看源代碼:

public static Toast makeText(Context context, CharSequence text, @Duration int duration) {return makeText(context, null, text, duration);}public static Toast makeText(@NonNull Context context, @Nullable Looper looper,@NonNull CharSequence text, @Duration int duration) {Toast result = new Toast(context, looper);...return result;} 復制代碼

以上是我們使用Toast時調用的靜態方法,可以看到第二個方法有個參數Looper,雖然我們平時用的時候都傳入的是null,那這個Looper究竟有什么用呢?我們看看Toast的構造函數:

public Toast(@NonNull Context context, @Nullable Looper looper) {mContext = context;mTN = new TN(context.getPackageName(), looper);} 復制代碼

可以看出這個Looper其實是TN在用,我們看看它的構造函數:

TN(String packageName, @Nullable Looper looper) {if (looper == null) {// Use Looper.myLooper() if looper is not specified.looper = Looper.myLooper();if (looper == null) {throw new RuntimeException("Can't toast on a thread that has not called Looper.prepare()");}}} 復制代碼

以上代碼有簡化。可以看出當Looper為null的時候,會通過Looper.myLooper獲取一個當前的Looper。我們知道在主線程中系統已經為我們初始化了一個mainLooper,所以我們一般不用管。但是當我們子線程中如果沒有初始化Looper,這里調用Looper.myLooper就獲取不到一個Looper,則會拋出異常。所以當我們在子線程中使用Toast,使用Looper.prepare()方法初始化一個Looper并用Looper.loop()讓它啟動起來即可。

所以我們可以封裝一個可以在任何線程使用的Toast。

private static Toast toast = null;public static void showToast(Context context, String text) {Looper myLooper = Looper.myLooper();if (myLooper == null) {Looper.prepare();myLooper = Looper.myLooper();}if (toast == null) {toast = Toast.makeText(context, text, Toast.LENGTH_LONG);toast.setGravity(Gravity.CENTER, 0, 0);}toast.show();if ( myLooper != null) {Looper.loop();myLooper.quit();}} 復制代碼

我們初始化Toast之前先判斷當前線程的looper是否為空,為空則初始化一個新的myLooper,然后在調用Toast的show方法之后讓looper啟動起來即可。因為Looper的loop()方法是無限循環的,為了防止Looper阻塞線程,導致內存泄漏應該及時退出Looper。

喜歡的話點個贊的吧,你的贊是我更新的動力!


總結

以上是生活随笔為你收集整理的Android进阶:六、在子线程中直接使用 Toast 及其原理的全部內容,希望文章能夠幫你解決所遇到的問題。

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