子线程不显示Toast?

这篇具有很好参考价值的文章主要介绍了子线程不显示Toast?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Handler不仅在ANR过程中有用到,Toast中也用到了Handler。

代码如下:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        new Thread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(MainActivity.this,"子线程",Toast.LENGTH_SHORT).show();
            }
        }).start();

    }
}

运行安装,Logcat里面显示了异常如下:

    Process: com.exp.cpdemo, PID: 1961
    java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
        at android.os.Handler.<init>(Handler.java:200)
        at android.os.Handler.<init>(Handler.java:114)
        at android.widget.Toast$TN$2.<init>(Toast.java:336)
        at android.widget.Toast$TN.<init>(Toast.java:336)
        at android.widget.Toast.<init>(Toast.java:103)
        at android.widget.Toast.makeText(Toast.java:256)
        at com.exp.cpdemo.MainActivity$1.run(MainActivity.java:40)
        at java.lang.Thread.run(Thread.java:761)

设备是Android 7.1 系统,对应源码:
/frameworks/base/core/java/android/widget/Toast.java

为什么会抛出这个异常?

从makeText方法开始看:

    public static Toast makeText(Context context, CharSequence text, @Duration int duration) {
        Toast result = new Toast(context);

        LayoutInflater inflate = (LayoutInflater)
                context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View v = inflate.inflate(com.android.internal.R.layout.transient_notification, null);
        TextView tv = (TextView)v.findViewById(com.android.internal.R.id.message);
        tv.setText(text);
        
        result.mNextView = v;
        result.mDuration = duration;

        return result;
    }

初始化了一个Toast对象。看看Toast构造器里面的代码逻辑:

    public Toast(Context context) {
        mContext = context;
        mTN = new TN(context.getPackageName());
        mTN.mY = context.getResources().getDimensionPixelSize(
                com.android.internal.R.dimen.toast_y_offset);
        mTN.mGravity = context.getResources().getInteger(
                com.android.internal.R.integer.config_toastDefaultGravity);
    }

初始化了一个TN对象。继续看TN这个类:

    private static class TN extends ITransientNotification.Stub {
		......
        final Handler mHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
				...
            }
        };


        TN(String packageName) {
			...
        }
		
		...
	}

TN是Toast的静态内部类。在生成TN对象时,成员变量mHandler赋值逻辑执行,调用了Handler的默认构造器。接着看Android 7.1 Handler的源码:
/frameworks/base/core/java/android/os/Handler.java

    public Handler() {
        this(null, false);
    }

    public Handler(Callback callback, boolean async) {
        if (FIND_POTENTIAL_LEAKS) {
            final Class<? extends Handler> klass = getClass();
            if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
                    (klass.getModifiers() & Modifier.STATIC) == 0) {
                Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
                    klass.getCanonicalName());
            }
        }

        mLooper = Looper.myLooper();
        if (mLooper == null) {
            throw new RuntimeException(
                "Can't create handler inside thread that has not called Looper.prepare()");
        }
        mQueue = mLooper.mQueue;
        mCallback = callback;
        mAsynchronous = async;
    }

果然,在Handler的两参数构造方法中,抛出了上面看到的异常。

怎么解决?

知道了原因,添加两行代码就好了,如下:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        new Thread(new Runnable() {
            @Override
            public void run() {
                Looper.prepare();
                Toast.makeText(MainActivity.this,"子线程",Toast.LENGTH_SHORT).show();
                Looper.loop();
            }
        }).start();

    }
}

Toast显示成功了。
子线程不显示Toast?文章来源地址https://www.toymoban.com/news/detail-494133.html

到了这里,关于子线程不显示Toast?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Vant4】Vant4 样式不显示问题 && Toast 轻提示不显示 && Notify 消息提示不显示

    使用 Toast 轻提示 和 Notify 消息提示 时没有样式,如下图 引入所需的样式,例如: 我要使用 消息提示 (Notify),就引入 import \\\'vant/es/notify/style\\\' 我要使用 轻提示 (Toast),就引入 import \\\'vant/es/toast/style\\\' HomeView.vue End 2023/3/7 一改 【Vue3】vue3的keepAlive保存滚动位置 CKEditor5 添加代码高亮

    2023年04月18日
    浏览(44)
  • 从IO多路复用到redis线程模型

    Blocking IO - 阻塞IO NoneBlocking IO - 非阻塞IO IO multiplexing - IO多路复用 signal driven IO - 信号驱动IO asynchronous IO - 异步IO 最传统的一种IO模型,即在读写数据过程中会发生阻塞现象。 当用户线程发出IO请求之后,内核会去查看数据是否就绪,如果没有就绪就会等待数据就绪,而用户线

    2024年02月07日
    浏览(38)
  • sqlserver-查询有哪些存储过程用到指定的表

    syscomments https://learn.microsoft.com/zh-cn/sql/relational-databases/system-compatibility-views/sys-syscomments-transact-sql?redirectedfrom=MSDNview=sql-server-ver16 sysobjects https://learn.microsoft.com/zh-cn/sql/relational-databases/system-compatibility-views/sys-sysobjects-transact-sql?view=sql-server-ver16 sys.objects https://learn.microsoft.com/zh-cn

    2024年02月11日
    浏览(41)
  • Android中线程间的通信-Handler

    Handler机制在Android中主要用于线程间的通信,特别是处理从子线程向主线程(UI线程)传递消息和更新界面。 Message : Message  是在线程间传递的数据载体,它包含了需要处理的数据和一些额外的信息。 每个  Message  对象可以携带一个  what  值(整数类型),用于标识消息的

    2024年02月03日
    浏览(33)
  • 微信小程序toast组件(解决wx.showToast文本最多显示两行问题)

    创建toast组件  index.wxmi index.less index.json index.ts toast.js 使用 index.json index.wxml  index.ts  效果

    2024年02月12日
    浏览(88)
  • 自定义工作线程 HandlerThread + new Handler(handlerThread.getLooper())

    自定义工作线程 HandlerThread + new Handler(handlerThread.getLooper()) 的写法如下: HandlerThread handlerThread = new HandlerThread(\\\"Data\\\"); handlerThread.start(); 创建了一个名为Data的新线程,并且这个线程是一个 HandlerThread ,它内部已经初始化了 Looper。当调用 handlerThread.start() 时,该线程会启动并开始

    2024年01月16日
    浏览(28)
  • 巡检过程中有哪些注意事项?智能巡检了解一下

    智能巡检系统是现场过程管理的生产力革命,由人工记录蝶化为掌上电脑运作,适用于设备运行值班记录、仓库/资产管理、设备巡检保养、安全巡更、机房值守、基站维护等一切重复性的工作管理。   安全巡检的目的在于识别信息系统存在的安全脆弱性、分析信息系统存在

    2024年02月07日
    浏览(48)
  • 【Android】多线程编程、异步消息处理机制以及new Handler()被标记为过时的解决办法,解决Handler内存泄漏问题和AsyncTask的基本用法

    1.1 弱引用 WeakReference (弱引用)是一种在Java中用于管理对象的引用的特殊引用类型。它的作用是在垃圾回收过程中,允许对象在没有强引用指向它时被回收( 当一个对象只有弱引用指向它,而没有强引用指向它时,垃圾回收器可能会在下一次垃圾回收时回收该对象,即使系

    2024年02月04日
    浏览(48)
  • debug - 只要在内存中有显示相关的数据, 就会被CE找到

    自己写了一个demo, 想验证一下, 如果不让显示值和实际值是一个地址(不直接使用结构, 而是用函数从结构中取值, 然后通过函数返回值给显示值用, 是否可以给CE增加一些麻烦? 发现不好使:P 因为实际值也是有地址的, 一样会被CE找到… CE在查找/定位数据方面, 真是利器. 我在de

    2024年02月20日
    浏览(28)
  • 安卓在子线程中实现更新UI界面的三种方法 Handler+Message、runOnUiThread、控件.post()

    1.说明 安卓中UI线程为主线程,更新UI界面必须在主线程中进行,在子线程中实现更新UI界面的三种方法:Handler、RunOnUiThread、控件.post() 2.1 Handler (1)定义handler (2)使用 2.2 控件.post() 2.3 在子线程中使用 runOnUiThread

    2024年02月12日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包