如果我們想要在另一個Thread中操控 UI ,在Swing中我們可以直接使用(可能會有些問題,不過還是可以直接用),不過,在Android就不行了。
如果我們直接使用的話,會丟出一個 android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views 錯誤
我們必須透過Message的傳遞來達到目的。
也蠻簡單的,
在要被操作的UI物件中(如View)宣告一個 android.os.Handler 物件,
然後覆寫public void handleMessage(Message msg),在該方法中便可以對UI進行操作。
而在Thread中則負責送出android.os.Message 物件到該 Handler。
這樣說好像不夠清楚,看一下code就懂了
// 做一個可以利用Thread修改的View
public class MyView extends View implements Runnable
{
如果我們直接使用的話,會丟出一個 android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views 錯誤
我們必須透過Message的傳遞來達到目的。
也蠻簡單的,
在要被操作的UI物件中(如View)宣告一個 android.os.Handler 物件,
然後覆寫public void handleMessage(Message msg),在該方法中便可以對UI進行操作。
而在Thread中則負責送出android.os.Message 物件到該 Handler。
這樣說好像不夠清楚,看一下code就懂了
// 做一個可以利用Thread修改的View
public class MyView extends View implements Runnable
{
public static final int MEG_INVALIDATE = 9527; //自訂一個號碼
private Thread thread;
// Constructor
private Thread thread;
// Constructor
public AnimationView(Context context)
{
super(context);
}
public AnimationView(Context context, AttributeSet attrs)
{
super(context, attrs);
}
Handler handler = new Handler()
{
public AnimationView(Context context, AttributeSet attrs)
{
super(context, attrs);
}
Handler handler = new Handler()
{
public void handleMessage(Message msg)
{
switch (msg.what)
{
// 當收到的Message的代號為我們剛剛訂的代號就做下面的動作。
case MEG_INVALIDATE:
// 重繪UI
invalidate();
break;
{
switch (msg.what)
{
// 當收到的Message的代號為我們剛剛訂的代號就做下面的動作。
case MEG_INVALIDATE:
// 重繪UI
invalidate();
break;
}
super.handleMessage(msg);
}
super.handleMessage(msg);
}
};
// 建立 Thread,並開始
public void init()
{
thread = new Thread(this);
thread.start();
}
// 建立 Thread,並開始
public void init()
{
thread = new Thread(this);
thread.start();
}
// invalidate() 會呼叫到 onDraw
public void onDraw(Canvas canvas)
{
}
// Runnable 介面
public void onDraw(Canvas canvas)
{
}
// Runnable 介面
public void run()
{
Message m = new Message();
// 定義 Message的代號,handler才知道這個號碼是不是自己該處理的。
m.what = MEG_INVALIDATE;
handler.sendMessage(m);
}
}
{
Message m = new Message();
// 定義 Message的代號,handler才知道這個號碼是不是自己該處理的。
m.what = MEG_INVALIDATE;
handler.sendMessage(m);
}
}
沒有留言:
張貼留言