在子執行緒中直接使用 Toast 及其原理

2021-09-24 19:26:27 字數 1619 閱讀 7317

一般我們都把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) 

public static toast maketext(@nonnull context context, @nullable looper looper,

@nonnull charsequence text, @duration int duration)

以上是我們使用toast時呼叫的靜態方法,可以看到第二個方法有個引數looper,雖然我們平時用的時候都傳入的是null,那這個looper究竟有什麼用呢?我們看看toast的建構函式:

public toast(@nonnull context context, @nullable looper looper)
可以看出這個looper其實是tn在用,我們看看它的建構函式:

tn(string packagename, @nullable looper looper) 

}}

以上**有簡化。可以看出當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)

if (toast == null)

toast.show();

if ( mylooper != null)

}

我們初始化toast之前先判斷當前執行緒的looper是否為空,為空則初始化乙個新的mylooper,然後在呼叫toast的show方法之後讓looper啟動起來即可。因為looper的loop()方法是無限迴圈的,為了防止looper阻塞執行緒,導致記憶體洩漏應該及時退出looper。

在子執行緒中Toast

問題 直接在普通子執行緒中toast會報錯 錯誤關鍵 1.普通的執行緒不能直接new乙個handle,而toast初始化 中如下 片 public class toast 2.為什麼普通執行緒不能new乙個handle?handle類 如下 public handler looper類中的 片段 p...

在Yii中直接使用sql

在yii中直接使用sql,是建立在php擴充套件pdo的基礎之上。使用前,確保pdo已安裝 一 建立連線 1,查詢 query 方式一 最簡潔 sql select a.id,b.name,parts type,parts model,partmanufacturer,number,confirm ...

在Yii中直接使用sql

在yii中直接使用sql,是建立在php擴充套件pdo的基礎之上。使用前,確保pdo已安裝 一 建立連線 其中db是在.config main.php中配置的 二 使用sql 1,查詢 query 方式一 最簡潔 方式二 主要區別在查詢動作。可拆分為兩步 datareader command que...