java中 toast的意思,安卓toast是什么意思怎么用(详解:Toast提示、Snackbars和Alert)...

一般我们都把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。

写在最后

615141.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值