`
zhoujianghai
  • 浏览: 439722 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

在工作线程中创建Toast

阅读更多

在工作线程中创建Toast,代码如下:

 

private void showToast() {
		new Thread() {
			public void run() {
				
				Looper.prepare();
				Toast.makeText(ActivityA.this, "来自工作线程", 

Toast.LENGTH_SHORT).show();
				Looper.loop();
			}
		}.start();
	}
 

 

 

如果不加Looper.prepare();则会出现以下异常:

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

Looper.prepare()
 

 

所以 在工作线程中创建Toast 须创建Looper对象。Looper.prepare();会创建当前线程的Looper对象和对应的MessageQueue(消息队列)

 

 

请参看Toast.java源码。

 Toast.java 包含 这句代码:final Handler mHandler = new Handler();   

mHandler是Toast的一个final类型的成员变量,在Handler的构造方法中有如下代码:

 

if (mLooper == null) {
            throw new RuntimeException(
                "Can't create handler inside thread that has not called 

Looper.prepare()");
        }
 

 

创建了Toast对象后,调用show()方法,把mShow这个Runnable添加到工作线程的消息队列中,

 

消息队列是在创建Looper对象的时候创建好的。

如代码:

 

final Runnable mShow = new Runnable() {
            public void run() {
                handleShow();
            }
        };

public void show() {
            if (localLOGV) Log.v(TAG, "SHOW: " + this);
            mHandler.post(mShow);
        }

/**
     * Causes the Runnable r to be added to the message queue.
     * The runnable will be run on the thread to which this handler is 
     * attached. 
     *  
     */
    public final boolean post(Runnable r)
    {
       return  sendMessageDelayed(getPostMessage(r), 0);
    }
 

此时调用Looper.loop(),从消息队列中取出消息,并执行。

主要源码:

 /**

     *  Run the message queue in this thread. Be sure to call
     * {@link #quit()} to end the loop.
     */
    public static final void loop() {
        Looper me = myLooper();
        MessageQueue queue = me.mQueue;
        while (true) {
            Message msg = queue.next(); // might block
            ......
                msg.target.dispatchMessage(msg);
               ......
                msg.recycle();
            }
        }
    }
 

此时会调用:mShow的handleShow();

源码:

 public void handleShow() {

            if (localLOGV) Log.v(TAG, "HANDLE SHOW: " + this + " mView=" + mView
                    + " mNextView=" + mNextView);
            if (mView != mNextView) {
                // remove the old view if necessary
                handleHide();
                mView = mNextView;
                mWM = WindowManagerImpl.getDefault();
                final int gravity = mGravity;
                mParams.gravity = gravity;
                if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == 

Gravity.FILL_HORIZONTAL) {
                    mParams.horizontalWeight = 1.0f;
                }
                if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) == 

Gravity.FILL_VERTICAL) {
                    mParams.verticalWeight = 1.0f;
                }
                mParams.x = mX;
                mParams.y = mY;
                mParams.verticalMargin = mVerticalMargin;
                mParams.horizontalMargin = mHorizontalMargin;
                if (mView.getParent() != null) {
                    if (localLOGV) Log.v(
                            TAG, "REMOVE! " + mView + " in " + this);
                    mWM.removeView(mView);
                }
                if (localLOGV) Log.v(TAG, "ADD! " + mView + " in " + this);
                mWM.addView(mView, mParams);
            }
        }
 

mWM.addView(mView, mParams);把Toast对应的view添加到当前Window中。

举一反三:

基于以上原理,可以实现这样的效果,拖动GridView里的ImageView元素,改变元素在GridView的位置。

分享到:
评论

相关推荐

    如何在线程中正确使用Toast显示提示信息

    在 run 方法中,我们首先将要显示的信息设置到 TextView 中,然后使用 Toast.makeText 方法创建一个 Toast 对象,并使用 show 方法将其显示出来。 需要注意的是,在在线程中使用 Toast 时,需要使用主Activity 的 ...

    Qt仿Android的toast控件效果

    接下来,我们将讨论如何在Qt中创建toast控件。这通常涉及到以下步骤: 1. **定义Toast类**:创建一个新的Qt Widget类,命名为`Toast`,继承自`QWidget`。在这个类中,我们需要设置控件的基本属性,如大小、颜色、...

    androidToast大全(五种情形)[归类].pdf

    如果需要在Toast中显示图片,可以通过获取Toast的布局视图,并向其中添加ImageView。首先获取Toast的视图,然后创建ImageView并设置图片资源,最后将ImageView添加到Toast的布局中。以下代码展示了如何在Toast中添加...

    Toast的几行代码

    在主线程中频繁使用`Toast`可能会阻塞UI,因此建议在子线程中创建并显示`Toast`,并通过`runOnUiThread`确保在UI线程执行: ```java context.runOnUiThread(new Runnable() { @Override public void run() { ...

    Toast的各种用法

    在主线程中创建`Toast`是安全的,但在其他线程中则需要处理。你可以使用`runOnUiThread`或`Handler`确保`Toast`在UI线程中显示: ```java new Thread(new Runnable() { @Override public void run() { // 在子...

    toast 演示

    7. 注意事项:`Toast`不是线程安全的,应在UI线程中创建和显示。此外,`Toast`是全局的,同一时间只能显示一个`Toast`。 通过这个“Toast演示”,初学者不仅可以了解`Toast`的基本用法,还可以学习到如何在实际项目...

    android 解决Toast重复显示问题

    3. **检查线程**:在多线程环境中,确保`Toast`的创建和显示都在主线程进行,因为`Toast`必须在UI线程中显示。 4. **避免循环调用**:如果`Toast`在循环或定时任务中使用,可以设置一个标志位来控制是否需要显示,...

    android service thread toast handler

    开发者可能通过创建一个新的`Thread`,在该线程中执行任务,并使用`Handler`将完成任务的消息传回主线程,以便在主线程中调用`Toast`显示信息。 总之,理解并熟练运用`Service`、`Thread`、`Toast`和`Handler`是...

    Android Toast 自定义背景、图片 随心使用

    值得注意的是,`Toast`是线程安全的,可以在任何线程中创建和显示,但在主线程中调用`show()`方法以确保UI更新的正常进行。此外,`Toast`的生命周期较短,一旦显示完毕,它就会自动消失,无需手动清理。 在实际项目...

    android service toast 01

    然而,Service通常运行在自己的工作线程中,这意味着在Service中直接使用Toast可能会导致`android.view.ViewRootImpl$CalledFromWrongThreadException`异常。为了解决这个问题,有以下两种常见方法: 1. 使用`...

    Qt仿安卓Toast效果.zip

    在本文中,我们将深入探讨如何在Qt环境中实现一个仿安卓Toast效果的功能,这将帮助开发者在他们的Qt应用中创建类似Android系统中短暂显示信息的组件。这个功能是跨平台的,可以在Windows和Linux(如Ubuntu)等操作...

    android中load_Toast_dialog

    为了实现上述功能,开发者需要对Android的生命周期有深入理解,熟悉线程管理,了解如何在主线程和工作线程之间进行通信。此外,还需要掌握布局设计和UI组件的使用,以便创建美观且易于使用的`Dialog`和`Toast`。 在...

    Toast用法详解(各种自定义Toast)实例

    由于`Toast`不是线程安全的,因此应该确保在主线程中创建和显示`Toast`。在非主线程中,可以使用`runOnUiThread()`: ```java context.runOnUiThread(new Runnable() { @Override public void run() { Toast....

    五种不同的Toast

    默认情况下,`Toast`在主线程中显示,但在某些场景下,你可能需要在子线程中使用`Toast`。由于Android UI操作必须在主线程进行,因此你需要使用`runOnUiThread()`方法。例如: ```java new Thread(() -> { try {...

    Android Toast各种使用方法及DEMO

    如果在主线程以外的地方显示`Toast`,需要确保在UI线程中执行,可以使用`runOnUiThread()`: ```java context.runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(context, "异步...

    Bamboy自定义Toast

    6. 处理多线程问题:如果`Toast`在非主线程中显示,需要确保在正确的线程中进行显示操作,通常使用`runOnUiThread`或`Handler`来处理。 7. 销毁`Toast`:当不再需要`Toast`时,可以调用`cancel()`方法来取消显示,...

    在android中Toast提示的特效功能

    如果需要在其他线程中使用`Toast`,可以使用`runOnUiThread()`或`Handler`来确保操作在主线程执行。 9. **适配不同设备和屏幕尺寸** - 考虑到不同设备的屏幕尺寸和分辨率,应适当调整`Toast`的大小和位置,使其在...

    你可能不知道的Toast用法

    在多线程环境中,确保在主线程中创建和显示`Toast`,因为它是不线程安全的。可以使用`runOnUiThread()`或`Handler`来保证这一点。 6. **全局`Toast`** 为了在多个地方方便地使用`Toast`,你可以创建一个全局的`...

    android的Toast提示框优化

    在大型项目中,为了统一管理`Toast`的显示,可以创建一个全局的`Toast`工具类,提供静态方法来显示`Toast`,这样可以在任何地方方便地调用,同时便于后期维护和修改。 8. **线程安全** 考虑到`Toast`可能会在多个...

Global site tag (gtag.js) - Google Analytics