在子线程中Toast

最近在些一个ToastUtil,用于统一新公司项目中的toast提示,先贴出ToastUtil的代码吧,只有简短几行

package com.luluyou.licai.util;

import android.os.Handler;
import android.os.Looper;
import android.support.annotation.StringRes;
import android.view.Gravity;
import android.widget.Toast;

import com.luluyou.licai.system.ZKBCApplication;

import java.lang.ref.WeakReference;

public class ToastUtil {

    private static WeakReference<Toast> toastWeakReference;

    public static void shortToast(CharSequence character){
        toastOnUIThread(character,Toast.LENGTH_SHORT,false);
    }

    public static void shortToast(@StringRes int resId){
        shortToast(ZKBCApplication.getInstance().getText(resId));
    }

    public static void shortCenterToast(CharSequence character){
        toastOnUIThread(character,Toast.LENGTH_SHORT,true);
    }

    public static void shortCenterToast(@StringRes int resId){
        shortCenterToast(ZKBCApplication.getInstance().getText(resId));
    }


    private static void toastOnUIThread(CharSequence character,/*@Toast.Duration*/ int duration,boolean isCenter){
        if(Looper.myLooper() == Looper.getMainLooper()){    //主线程
            toast(character,duration,isCenter);
        }else{      //子线程
            new Handler(Looper.getMainLooper()).post(() -> toast(character,duration,isCenter));
        }
    }

    private static void toast(CharSequence character,/*@Toast.Duration*/ int duration,boolean isCenter){
        if(toastWeakReference == null || toastWeakReference.get() == null) {
            toastWeakReference = new WeakReference(Toast.makeText(ZKBCApplication.getInstance(),character,duration));
        }
        if(isCenter){
            toastWeakReference.get().setGravity(Gravity.CENTER, 0, 0);
        }else{
//            toastWeakReference.get().setGravity(Gravity.CENTER|Gravity.BOTTOM, 0, ZKBCApplication.getInstance().getResources().getDimensionPixelSize(
//                    com.android.internal.R.dimen.toast_y_offset));    //不能使用隐藏得内部资源,<dimen name="toast_y_offset">64dip</dimen>
            toastWeakReference.get().setGravity(Gravity.CENTER|Gravity.BOTTOM, 0, Helper.dpToPx(64,ZKBCApplication.getInstance()));
        }
        toastWeakReference.get().setText(character);
        toastWeakReference.get().show();
    }

}

引出一个需求,在非ui线程也可以使用toast
所以有了这行代码:

else{      //子线程
            new Handler(Looper.getMainLooper()).post(() -> toast(character,duration,isCenter));
        }

上面的代码,是将toast(…)的执行放到了主线程中了.

否则,在主线程中调用Toast,会出现如下异常

java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

出现这个错误的原因是toast依赖于handle,用于处理视图的展示隐藏时间,而主线程(UI线程)是实现了Looper的,子线程若没有looper,Toast进行执行前的检查会抛出异常。

看源码可知,Toast 实际是window.addView(),在window上添加一个视图,通过handle控制展示隐藏。
这部分源码的分析,下次再写。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值