首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > 移动开发 >

在工作线程中创造Toast

2012-09-10 
在工作线程中创建Toast在工作线程中创建Toast,代码如下:?private void showToast() {new Thread() {public

在工作线程中创建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的位置。

热点排行