最近因為個人原因,很久沒有更文章,感謝關注的小夥伴,望諒解!
一般我們都把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。
喜歡的話點個讚的吧,你的贊是我更新的動力!